zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

Android静默方式实现批量安装卸载应用程序的深入分析

Android批量安装应用程序 实现 方式 卸载 深入分析
2023-06-13 09:15:01 时间
前段时间做了一个批量安装卸载应用程序的小应用,由于安装卸载应用程序的部分API是隐藏的,所以必须在ubuntu下下载Android系统源码,并编译之后使用MM命令编译生成APK文件,其实也难。

思路是这样的,在XX/packages/apps目录下有一个PackageInstaller的应用程序,Android机器中安装卸载都是由这个应用程序完成的。但是它没有批量安装和卸载的功能,如果要在自己的应用程序中添加批量安装和卸载的功能,其实很简单,只需要参考PakcageInstaller里面的安装卸载代码加个循环就可以了。但值得注意的是在编译的过程中必须复制PackageInstaller里面的Android.mk文件,修改文件为工程目录名。
好了,废话不再多说,下面是关键代码
1、Android.mk文件
复制代码代码如下:

LOCAL_PATH:=$(callmy-dir)
include$(CLEAR_VARS)

LOCAL_MODULE_TAGS:=optional

LOCAL_SRC_FILES:=$(callall-subdir-java-files)

LOCAL_PACKAGE_NAME:=PackageInstaller
LOCAL_CERTIFICATE:=platform

include$(BUILD_PACKAGE)

复制代码代码如下:

   LOCAL_PATH:=$(callmy-dir) 
   include$(CLEAR_VARS) 

   LOCAL_MODULE_TAGS:=optional 

   LOCAL_SRC_FILES:=$(callall-subdir-java-files) 

   LOCAL_PACKAGE_NAME:=PackageInstaller 
   LOCAL_CERTIFICATE:=platform 

   include$(BUILD_PACKAGE) 

2、PakcageInstaller.java文件(关键代码)
复制代码代码如下:
   packagecn.ceadic.apkmgr;

   importjava.io.File;
   importjava.io.FileNotFoundException;
   importjava.io.FileOutputStream;
   importjava.io.IOException;

   importandroid.content.Context;
   importandroid.content.Intent;
   importandroid.content.pm.PackageInfo;
   importandroid.content.pm.PackageManager;
   importandroid.content.pm.PackageManager.NameNotFoundException;
   importandroid.net.Uri;
   importandroid.util.Log;

   importandroid.content.pm.IPackageInstallObserver;
   importandroid.content.pm.IPackageDeleteObserver;
   importandroid.os.FileUtils;

    
   publicclassPackageInstaller{

       privateFilemTmpFile;
       privatefinalStringTMP_FILE_NAME="tmpCopy.apk";

       privatefinalstaticStringTAG="PackInstaller";
       privateContextmContext;

       publicPackageInstaller(Contextcontext){
           mContext=context;
       }

        
       publicvoidinstall(Stringpath,StringpackageName){
            Intentintent=newIntent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(newFile(path)),
            "application/vnd.android.package-archive");
            mContext.startActivity(intent);
       }

       publicvoidinstatllBatch(Stringpath,StringpackageName){

           Log.i(TAG,"path="+path);
           intinstallFlags=0;
           PackageManagerpm=mContext.getPackageManager();
           try{
               PackageInfopi=pm.getPackageInfo(packageName,
                       PackageManager.GET_UNINSTALLED_PACKAGES);
               if(pi!=null){
                   installFlags|=PackageManager.INSTALL_REPLACE_EXISTING;
               }
           }catch(NameNotFoundExceptione){
           }
           if((installFlags&PackageManager.INSTALL_REPLACE_EXISTING)!=0){
               Log.w(TAG,"Replacingpackage:"+packageName);
           }

           //Createtempfilebeforeinvokinginstallapi
           mTmpFile=createTempPackageFile(path);
           if(mTmpFile==null){
               //Messagemsg=mHandler.obtainMessage(INSTALL_COMPLETE);
               //msg.arg1=PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
               //mHandler.sendMessage(msg);
               return;
           }
           UrimPackageURI=Uri.parse("file://"+mTmpFile.getPath());
           StringinstallerPackageName=mContext.getIntent().getStringExtra(
                   Intent.EXTRA_INSTALLER_PACKAGE_NAME);

           PackageInstallObserverobserver=newPackageInstallObserver();
           pm.installPackage(mPackageURI,observer,installFlags,
                   installerPackageName);
       }

       privateFilecreateTempPackageFile(StringfilePath){
           FiletmpPackageFile=mContext.getFileStreamPath(TMP_FILE_NAME);
           if(tmpPackageFile==null){
               Log.w(TAG,"Failedtocreatetempfile");
               returnnull;
           }
           if(tmpPackageFile.exists()){
               tmpPackageFile.delete();
           }
           //Openfiletomakeitworldreadable
           FileOutputStreamfos;
           try{
               fos=openFileOutput(TMP_FILE_NAME,MODE_WORLD_READABLE);
           }catch(FileNotFoundExceptione1){
               Log.e(TAG,"Erroropeningfile"+TMP_FILE_NAME);
               returnnull;
           }
           try{
               fos.close();
           }catch(IOExceptione){
               Log.e(TAG,"Erroropeningfile"+TMP_FILE_NAME);
               returnnull;
           }

           FilesrcPackageFile=newFile(filePath);
           if(!FileUtils.copyFile(srcPackageFile,tmpPackageFile)){
               Log.w(TAG,"Failedtomakecopyoffile:"+srcPackageFile);
               returnnull;
           }
           returntmpPackageFile;
       }

       privateclassPackageInstallObserverextendsIPackageInstallObserver.Stub{
           publicvoidpackageInstalled(StringpackageName,intreturnCode){
               //Messagemsg=mHandler.obtainMessage(INSTALL_COMPLETE);
               //msg.arg1=returnCode;
               //mHandler.sendMessage(msg);
               Log.i(TAG,"====INSTALL_COMPLETE");
           }
       }

       privateclassPackageDeleteObserverextendsIPackageDeleteObserver.Stub{
           publicvoidpackageDeleted(booleansucceeded){
   //           Messagemsg=mHandler.obtainMessage(UNINSTALL_COMPLETE);
   //           msg.arg1=succeeded?SUCCEEDED:FAILED;
   //           mHandler.sendMessage(msg);
               Log.i(TAG,"====UNINSTALL_COMPLETE");
           }
       }

       publicvoiduninstall(StringpackageName){
           UripackageURI=Uri.parse("package:"+packageName);
           IntentuninstallIntent=newIntent(Intent.ACTION_DELETE,
           packageURI);
           mContext.startActivity(uninstallIntent);
       }

       publicvoiduninstallBatch(StringpackageName){
           PackageDeleteObserverobserver=newPackageDeleteObserver();
           mContext.getPackageManager().deletePackage(packageName,observer,0);

       }
   } 

复制代码代码如下:
   packagecn.ceadic.apkmgr; 

   importjava.io.File; 
   importjava.io.FileNotFoundException; 
   importjava.io.FileOutputStream; 
   importjava.io.IOException; 

   importandroid.content.Context; 
   importandroid.content.Intent; 
   importandroid.content.pm.PackageInfo; 
   importandroid.content.pm.PackageManager; 
   importandroid.content.pm.PackageManager.NameNotFoundException; 
   importandroid.net.Uri; 
   importandroid.util.Log; 

   importandroid.content.pm.IPackageInstallObserver; 
   importandroid.content.pm.IPackageDeleteObserver; 
   importandroid.os.FileUtils; 

     
   publicclassPackageInstaller{ 

       privateFilemTmpFile; 
       privatefinalStringTMP_FILE_NAME="tmpCopy.apk"; 

       privatefinalstaticStringTAG="PackInstaller"; 
       privateContextmContext; 

       publicPackageInstaller(Contextcontext){ 
           mContext=context; 
       } 

         
       publicvoidinstall(Stringpath,StringpackageName){ 
            Intentintent=newIntent(Intent.ACTION_VIEW); 
            intent.setDataAndType(Uri.fromFile(newFile(path)), 
            "application/vnd.android.package-archive"); 
            mContext.startActivity(intent); 
       } 

       publicvoidinstatllBatch(Stringpath,StringpackageName){ 

           Log.i(TAG,"path="+path); 
           intinstallFlags=0; 
           PackageManagerpm=mContext.getPackageManager(); 
           try{ 
               PackageInfopi=pm.getPackageInfo(packageName, 
                       PackageManager.GET_UNINSTALLED_PACKAGES); 
               if(pi!=null){ 
                   installFlags|=PackageManager.INSTALL_REPLACE_EXISTING; 
               } 
           }catch(NameNotFoundExceptione){ 
           } 
           if((installFlags&PackageManager.INSTALL_REPLACE_EXISTING)!=0){ 
               Log.w(TAG,"Replacingpackage:"+packageName); 
           } 

           //Createtempfilebeforeinvokinginstallapi 
           mTmpFile=createTempPackageFile(path); 
           if(mTmpFile==null){ 
               //Messagemsg=mHandler.obtainMessage(INSTALL_COMPLETE); 
               //msg.arg1=PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 
               //mHandler.sendMessage(msg); 
               return; 
           } 
           UrimPackageURI=Uri.parse("file://"+mTmpFile.getPath()); 
           StringinstallerPackageName=mContext.getIntent().getStringExtra( 
                   Intent.EXTRA_INSTALLER_PACKAGE_NAME); 

           PackageInstallObserverobserver=newPackageInstallObserver(); 
           pm.installPackage(mPackageURI,observer,installFlags, 
                   installerPackageName); 
       } 

       privateFilecreateTempPackageFile(StringfilePath){ 
           FiletmpPackageFile=mContext.getFileStreamPath(TMP_FILE_NAME); 
           if(tmpPackageFile==null){ 
               Log.w(TAG,"Failedtocreatetempfile"); 
               returnnull; 
           } 
           if(tmpPackageFile.exists()){ 
               tmpPackageFile.delete(); 
           } 
           //Openfiletomakeitworldreadable 
           FileOutputStreamfos; 
           try{ 
               fos=openFileOutput(TMP_FILE_NAME,MODE_WORLD_READABLE); 
           }catch(FileNotFoundExceptione1){ 
               Log.e(TAG,"Erroropeningfile"+TMP_FILE_NAME); 
               returnnull; 
           } 
           try{ 
               fos.close(); 
           }catch(IOExceptione){ 
               Log.e(TAG,"Erroropeningfile"+TMP_FILE_NAME); 
               returnnull; 
           } 

           FilesrcPackageFile=newFile(filePath); 
           if(!FileUtils.copyFile(srcPackageFile,tmpPackageFile)){ 
               Log.w(TAG,"Failedtomakecopyoffile:"+srcPackageFile); 
               returnnull; 
           } 
           returntmpPackageFile; 
       } 

       privateclassPackageInstallObserverextendsIPackageInstallObserver.Stub{ 
           publicvoidpackageInstalled(StringpackageName,intreturnCode){ 
               //Messagemsg=mHandler.obtainMessage(INSTALL_COMPLETE); 
               //msg.arg1=returnCode; 
               //mHandler.sendMessage(msg); 
               Log.i(TAG,"====INSTALL_COMPLETE"); 
           } 
       } 

       privateclassPackageDeleteObserverextendsIPackageDeleteObserver.Stub{ 
           publicvoidpackageDeleted(booleansucceeded){ 
   //           Messagemsg=mHandler.obtainMessage(UNINSTALL_COMPLETE); 
   //           msg.arg1=succeeded?SUCCEEDED:FAILED; 
   //           mHandler.sendMessage(msg); 
               Log.i(TAG,"====UNINSTALL_COMPLETE"); 
           } 
       } 

       publicvoiduninstall(StringpackageName){ 
           UripackageURI=Uri.parse("package:"+packageName); 
           IntentuninstallIntent=newIntent(Intent.ACTION_DELETE, 
           packageURI); 
           mContext.startActivity(uninstallIntent); 
       } 

       publicvoiduninstallBatch(StringpackageName){ 
           PackageDeleteObserverobserver=newPackageDeleteObserver(); 
           mContext.getPackageManager().deletePackage(packageName,observer,0); 

       } 
   } 

3、别忘记添加权限
复制代码代码如下:
   <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
       <uses-permissionandroid:name="android.permission.INSTALL_PACKAGES"/>
       <uses-permissionandroid:name="android.permission.DELETE_PACKAGES"/>
       <uses-permissionandroid:name="android.permission.CLEAR_APP_CACHE"/>
       <uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>
       <uses-permissionandroid:name="android.permission.CLEAR_APP_USER_DATA"/> 

复制代码代码如下:
   <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
       <uses-permissionandroid:name="android.permission.INSTALL_PACKAGES"/> 
       <uses-permissionandroid:name="android.permission.DELETE_PACKAGES"/> 
       <uses-permissionandroid:name="android.permission.CLEAR_APP_CACHE"/> 
       <uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/> 
       <uses-permissionandroid:name="android.permission.CLEAR_APP_USER_DATA"/> 

以上代码在Android2.1的SDK中编译通过,并正确批量安装卸载应用程序