应用 默认加了systemUid和系统签名
广播在PMS里发送frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
1.uninstall
Neither user 10083 nor current process has android.permission.REQUEST_DELETE_PACKAGES.
配置权限
android:sharedUserId="android.uid.system"
<!-- Allows an application to delete packages. <p>Not for use by third-party applications. <p>Starting in {@link android.os.Build.VERSION_CODES#N}, user confirmation is requested when the application deleting the package is not the same application that installed the package. --> <permission android:name="android.permission.DELETE_PACKAGES" android:protectionLevel="signature|privileged" /> <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/>
public void uninstallApp(String packageName) { Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent sender = PendingIntent.getActivity(getContext(), 0, intent, 0); PackageInstaller mPackageInstaller = getContext().getPackageManager().getPackageInstaller(); mPackageInstaller.uninstall(packageName, sender.getIntentSender());// 卸载APK }
会收到 android.intent.action.PACKAGE_REMOVED 广播
2.disable
权限
<!-- Allows an application to change whether an application component (other than its own) is enabled or not. <p>Not for use by third-party applications. --> <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" android:protectionLevel="signature|privileged" />
public void disableApp(String packageName){ PackageManager mPackageManager=getContext().getPackageManager(); mPackageManager.setApplicationEnabledSetting(packageName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP); }
会收到 android.intent.action.PACKAGE_CHANGED 广播
3.enable
public void enableApp(String pkgName) { final PackageManager pm = mContext.getPackageManager(); try { int state = pm.getApplicationEnabledSetting(pkgName); Log.d("TAG", "enableApplication state: " + state + " pkgName:" + pkgName); if (state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) return; pm.setApplicationEnabledSetting(pkgName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0); } catch (IllegalArgumentException exeption) { Log.w("TAG", "enableApplication error:" + exeption.getMessage()); } }
会受到 android.intent.action.PACKAGE_CHANGED 广播
4.install
方法1:这种方法比较麻烦 需要系统权限 SeLinux权限也会报错
android.permission.INTERACT_ACROSS_USERS_FULL
public boolean installApp(String packageName,String apkPath) { Process process = null; BufferedReader successResult = null; BufferedReader errorResult = null; StringBuilder successMsg = new StringBuilder(); StringBuilder errorMsg = new StringBuilder(); try { process = new ProcessBuilder("pm", "install", "-i", packageName, "-r", apkPath).start(); successResult = new BufferedReader(new InputStreamReader(process.getInputStream())); errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream())); String s; while ((s = successResult.readLine()) != null) { successMsg.append(s); } while ((s = errorResult.readLine()) != null) { errorMsg.append(s); } } catch (Exception e) { } finally { try { if (successResult != null) { successResult.close(); } if (errorResult != null) { errorResult.close(); } } catch (Exception e) { } if (process != null) { process.destroy(); } } Log.e("result", "" + errorMsg.toString()); //如果含有“success”认为安装成功 return successMsg.toString().equalsIgnoreCase("success"); }
方法2:比较简单 适合普通app使用
申请权限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
逻辑代码 :
private void installAPk(File apkFile) { Intent intent = new Intent(Intent.ACTION_VIEW); //如果没有设置SDCard写权限,或者没有sdcard,apk文件保存在内存中,需要授予权限才能安装 try { String[] command = {"chmod", "777", apkFile.toString()}; ProcessBuilder builder = new ProcessBuilder(command); builder.start(); } catch (IOException ignored) { Log.e(TAG,ignored.toString()); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { Log.e(TAG, "installAPk: " + apkFile.getAbsolutePath()); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Uri contentUri = FileProvider.getUriForFile(this, "com.example.overlay.idea.fileprovider",apkFile); intent.setDataAndType(contentUri, "application/vnd.android.package-archive"); } else { intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive"); } intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getApplication().startActivity(intent); }
会收到 android.intent.action.PACKAGE_ADDED 广播
5.apk升级
会收到 android.intent.action.PACKAGE_REPLACED 广播