【Android应用开发】-(18)静默方式实现批量安装卸载应用程序

     前段时间做了一个批量安装卸载应用程序的小应用,由于安装卸载应用程序的部分API是隐藏的,所以必须在ubuntu下下载Android系统源码,并编译之后使用MM命令编译生成APK文件,其实也难。思路是这样的,在XX/packages/apps目录下有一个PackageInstaller的应用程序,Android机器中安装卸载都是由这个应用程序完成的。但是它没有批量安装和卸载的功能,如果要在自己的应用程序中添加批量安装和卸载的功能,其实很简单,只需要参考PakcageInstaller里面的安装卸载代码加个循环就可以了。但值得注意的是在编译的过程中必须复制PackageInstaller里面的Android.mk文件,修改文件为工程目录名。好了,废话不再多说,下面是关键代码

   1、 Android.mk文件

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := PackageInstaller
LOCAL_CERTIFICATE := platform

include $(BUILD_PACKAGE)


   2、PakcageInstaller.java文件(关键代码)

package cn.ceadic.apkmgr;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

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

import android.content.pm.IPackageInstallObserver;
import android.content.pm.IPackageDeleteObserver;
import android.os.FileUtils;


public class PackageInstaller {
	
	private File mTmpFile;
	private final String TMP_FILE_NAME = "tmpCopy.apk";

	private final static String TAG = "PackInstaller";
	private Context mContext;

	public PackageInstaller(Context context) {
		mContext = context;
	}

	
	public void install(String path,String packageName){
		 Intent intent = new Intent(Intent.ACTION_VIEW);
		 intent.setDataAndType(Uri.fromFile(new File(path)),
		 "application/vnd.android.package-archive");
		 mContext.startActivity(intent);
	}
	
	public void instatllBatch(String path, String packageName) {

		Log.i(TAG, "path=" + path);
		int installFlags = 0;
		PackageManager pm = mContext.getPackageManager();
		try {
			PackageInfo pi = pm.getPackageInfo(packageName,
					PackageManager.GET_UNINSTALLED_PACKAGES);
			if (pi != null) {
				installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
			}
		} catch (NameNotFoundException e) {
		}
		if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
			Log.w(TAG, "Replacing package:" + packageName);
		}

		// Create temp file before invoking install api
		mTmpFile = createTempPackageFile(path);
		if (mTmpFile == null) {
			// Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);
			// msg.arg1 = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
			// mHandler.sendMessage(msg);
			return;
		}
		Uri mPackageURI = Uri.parse("file://" + mTmpFile.getPath());
		String installerPackageName = mContext.getIntent().getStringExtra(
				Intent.EXTRA_INSTALLER_PACKAGE_NAME);

		PackageInstallObserver observer = new PackageInstallObserver();
		pm.installPackage(mPackageURI, observer, installFlags,
				installerPackageName);
	}

	private File createTempPackageFile(String filePath) {
		File tmpPackageFile = mContext.getFileStreamPath(TMP_FILE_NAME);
		if (tmpPackageFile == null) {
			Log.w(TAG, "Failed to create temp file");
			return null;
		}
		if (tmpPackageFile.exists()) {
			tmpPackageFile.delete();
		}
		// Open file to make it world readable
		FileOutputStream fos;
		try {
			fos = openFileOutput(TMP_FILE_NAME, MODE_WORLD_READABLE);
		} catch (FileNotFoundException e1) {
			Log.e(TAG, "Error opening file " + TMP_FILE_NAME);
			return null;
		}
		try {
			fos.close();
		} catch (IOException e) {
			Log.e(TAG, "Error opening file " + TMP_FILE_NAME);
			return null;
		}

		File srcPackageFile = new File(filePath);
		if (!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) {
			Log.w(TAG, "Failed to make copy of file: " + srcPackageFile);
			return null;
		}
		return tmpPackageFile;
	}

	private class PackageInstallObserver extends IPackageInstallObserver.Stub {
		public void packageInstalled(String packageName, int returnCode) {
			// Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);
			// msg.arg1 = returnCode;
			// mHandler.sendMessage(msg);
			Log.i(TAG, "====INSTALL_COMPLETE");
		}
	}
	
	private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
        public void packageDeleted(boolean succeeded) {
//            Message msg = mHandler.obtainMessage(UNINSTALL_COMPLETE);
//            msg.arg1 = succeeded?SUCCEEDED:FAILED;
//            mHandler.sendMessage(msg);
            Log.i(TAG, "====UNINSTALL_COMPLETE");
        }
    }
    
    public void uninstall(String packageName){
    	Uri packageURI = Uri.parse("package:" + packageName);
		Intent uninstallIntent = new Intent(Intent.ACTION_DELETE,
		packageURI);
		mContext.startActivity(uninstallIntent);
	}
	
	public void uninstallBatch(String packageName) {
	    PackageDeleteObserver observer = new PackageDeleteObserver();
        mContext.getPackageManager().deletePackage(packageName, observer, 0);
		
	}
}


   3、别忘记添加权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
	<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
	<uses-permission android:name="android.permission.DELETE_PACKAGES" />
	<uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
	<uses-permission android:name="android.permission.READ_PHONE_STATE" />
	<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />

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

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 27
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值