应用 默认加了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 广播