PackageInstaller 类安装/卸载应用

前言:开发手机应用转到 TV 应用小半年了,最头疼的就是焦点问题。今天不说焦点,来看看应用商店的安装 / 卸载功能。


项目是中途接手的,安装方法一直使用的是 packageManager.installPackage(Uri var1, PackageInstallObserver var2, int var3, String var4) 这个 API,实现静默安装的功能。直到系统升级为 Android P,安装方法报错:

java.lang.NoClassDefFoundError: Failed resolution of: Landroid/content/pm/IPackageInstallObserver$Stub;

经查看 API 最新文档,查阅到注解“deprecated replaced by {@link PackageInstaller}”,需要改用 PackageInstaller 类来实现安装/卸载功能,Android API 21 添加了这个类。

具体实现:

注:因为应用商店做的是 系统应用,不需要在格外的去获取系统权限,若不是系统级应用,需要先获取对应安装/卸载权限再进行操作。

  1. 安装
/**
 * @param filepathApk 文件路径
 */
private void installPackage(String filepathApk) {
	try {
		PackageInstaller pi = mContext.getPackageManager().getPackageInstaller();
		//给定模式,创建新的参数,创建新安装会话,返回唯一 Id
		int sessionId= pi.createSession(new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL));
		//打开现有会话,主动执行工作
		PackageInstaller.Session session = pi.openSession(sessionId);
		long sizeBytes = 0;
		final File file = new File(filepathApk);
		if (file.isFile()) {
			sizeBytes = file.length();
		}
		InputStream in = null;
		OutputStream out = null;
		in = new FileInputStream(filepathApk);
		//打开一个流,将一个APK文件写入会话
		//指定有效长度系统将预先分配底层磁盘空间以优化磁盘上的放置
		out = session.openWrite("app_store_session", 0, sizeBytes);
		int total = 0;
		byte[] buffer = new byte[65536];
		int len;
		while ((len= in.read(buffer)) != -1) {
			total += len;
			out.write(buffer, 0, len);
		}
		//根据需要调用,用来确保字节已保留到磁盘
		session.fsync(out);
		in.close();
		out.close();
		MyLogger.Log().v("InstallApkViaPackageInstaller - Success: streamed apk " + total + " bytes");
		PendingIntent broadCastTest = PendingIntent.getBroadcast(
				mContext,
				sessionId,
				new Intent(ACTION_INSTALL_COMPLETE),
				PendingIntent.FLAG_UPDATE_CURRENT);
		//提交之前必须关闭所有流
		session.commit(broadCastTest.getIntentSender());
		session.close();
	} catch (Exception ex) {
		ex.printStackTrace();
	}
}

ACTION_INSTALL_COMPLETE 是自己声明的变量。

  1. 卸载
/**
 * @param packageName 应用包名
 */
private void uninstallPackage(String packageName) {
	Intent intent = new Intent(mContext, mContext.getClass());
	PendingIntent sender = PendingIntent.getActivity(mContext, 0, intent, 0);
	PackageInstaller mPackageInstaller = mContext.getPackageManager().getPackageInstaller();
	mPackageInstaller.uninstall(packageName, sender.getIntentSender());
}

了解此类相关点击 PackageInstaller
业务实现介绍至此,若有问题,欢迎交流。

你可能感兴趣的:(系统服务)