Android静默方式实现批量安装卸载应用程序
16lz
2021-01-23
前段时间做了一个批量安装卸载应用程序的小应用,由于安装卸载应用程序的部分API是隐藏的,所以必须在ubuntu下下载Android系统源码,并编译之后使用MM命令编译生成APK文件,其实也难。思路是这样的,在XX/packages/apps目录下有一个PackageInstaller的应用程序,Android机器中安装卸载都是由这个应用程序完成的。但是它没有批量安装和卸载的功能,如果要在自己的应用程序中添加批量安装和卸载的功能,其实很简单,只需要参考PakcageInstaller里面的安装卸载代码加个循环就可以了。但值得注意的是在编译的过程中必须复制PackageInstaller里面的Android.mk文件,修改文件为工程目录名。好了,废话不再多说,下面是关键代码
以上代码在Android2.1的SDK中编译通过,并正确批量安装卸载应用程序
1、 Android.mk文件
[plain] view plain copy
- 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文件(关键代码)
[java] view plain copy
- 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、别忘记添加权限
[html] view plain copy
- <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中编译通过,并正确批量安装卸载应用程序
更多相关文章
- Android使用Itext生成pdf文件
- android下创建文件夹和修改其权限的方法
- Android 将少量的数据文件保存在 data/data 目录下
- Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析
- Android编译系统中头文件搜索路径的顺序问题
- Android 如何利用proc有上层想kernel写文件
- 仿微信、短信、QQ等消息数目右上角红色小圆球气泡显示(基于Androi
- 如何在开发时可以让Android应用程序支持安装到SD卡