android动态设置是否允许应用卸载

摘要:通过广播设置全局参数控制应用是否允许卸载,全局参数在Launcher和PackageInstaller两个模块中使用到。此功能可用于MDM后台控制是否允许设备卸载应用。

1. 静态注册广播

由于系统安装和卸载的功能集中在PackageInstaller模块中,为了更好的调用并适配android标准接口,故将广播注册在PackageInstaller模块,同时添加写全局变量的权限。

java 复制代码
Index: frameworks/base/packages/PackageInstaller/AndroidManifest.xml
===================================================================
--- frameworks/base/packages/PackageInstaller/AndroidManifest.xml	(版本 360)
+++ frameworks/base/packages/PackageInstaller/AndroidManifest.xml	(版本 361)
@@ -18,6 +18,7 @@
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
     <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <!-- @ + -->
 
     <uses-permission android:name="com.google.android.permission.INSTALL_WEARABLE_PACKAGES" />
 
@@ -142,6 +143,16 @@
                   android:authorities="com.google.android.packageinstaller.wear.provider"
                   android:grantUriPermissions="true"
                   android:exported="true" />
+
+        <!-- @ + { -->
+        <receiver android:name=".UninstallAppStatusAddReceiver"
+                android:exported="true" >
+            <intent-filter>
+                <action android:name="com.example.launcher.UNINSTALL"/>
+            </intent-filter>
+        </receiver>
+	     <!-- @ + } -->
     </application>
 
 </manifest>

2. 收到广播后设置全局变量

接收到携带应用包名和卸载与否标志位的参数的广播后,将全局变量对应的包名设置为相对应的标志位。

java 复制代码
Index: frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/UninstallAppStatusAddReceiver.java
===================================================================
--- frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/UninstallAppStatusAddReceiver.java	(不存在的)
+++ frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/UninstallAppStatusAddReceiver.java	(版本 361)
@@ -0,0 +1,57 @@
+package com.android.packageinstaller;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Environment;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+
+
+public class UninstallAppStatusAddReceiver extends BroadcastReceiver {
+
+    private final static String ACTION_UNINSTALL = "com.example.launcher.UNINSTALL";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        Log.d("UninstallAppStatusAddReceiver", "onReceive: " + action);
+        if (ACTION_UNINSTALL.equals(action)) {
+            String pkgName = intent.getStringExtra("packageName");
+            int flag = intent.getIntExtra("flag",0);
+            if (!(TextUtils.isEmpty(pkgName))) {
+                Settings.System.putInt(context.getContentResolver(),pkgName, flag);
+            }
+        }
+    }
+}

3. 卸载时不做处理

在设置-应用中卸载

java 复制代码
Index: frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
===================================================================
--- frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java	(版本 360)
+++ frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java	(版本 361)
@@ -55,6 +55,7 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.util.Log;
 
 import com.android.packageinstaller.handheld.ErrorDialogFragment;
@@ -210,7 +211,15 @@
             }
         }
 
-        showConfirmationDialog();
+        // @ + {
+        int flag = Settings.System.getInt(getContentResolver(), mPackageName, 0);
+        if (flag == 0) {
+            showConfirmationDialog();
+        }
+        if (flag == 1) {
+            finish();
+        }
+        // @ + }
     }
 
     public DialogInfo getDialogInfo() {

在Launcher拖动不显示卸载

java 复制代码
Index: vendor/mediatek/proprietary/packages/apps/Launcher3/src/com/android/launcher3/ButtonDropTarget.java
===================================================================
--- vendor/mediatek/proprietary/packages/apps/Launcher3/src/com/android/launcher3/ButtonDropTarget.java	(版本 360)
+++ vendor/mediatek/proprietary/packages/apps/Launcher3/src/com/android/launcher3/ButtonDropTarget.java	(版本 361)
@@ -185,6 +185,13 @@
             setupItemInfo(dragObject.dragInfo);
             mActive = supportsDrop(dragObject.dragInfo);
         }
+        // @ + {
+        int flag = android.provider.Settings.System.getInt(
+                getContext().getContentResolver(),dragObject.dragInfo.getTargetPackage(), 0);
+        if (flag == 1) {
+            mActive = false;
+        }
+        // @ + }
         setVisibility(mActive ? View.VISIBLE : View.GONE);
 
         mAccessibleDrag = options.isAccessibleDrag;
相关推荐
CV资深专家5 小时前
在 Android 框架中,接口的可见性规则
android
daifgFuture9 小时前
Android 3D球形水平圆形旋转,旋转动态更换图片
android·3d
二流小码农10 小时前
鸿蒙开发:loading动画的几种实现方式
android·ios·harmonyos
爱吃西红柿!11 小时前
fastadmin fildList 动态下拉框默认选中
android·前端·javascript
悠哉清闲12 小时前
工厂模式与多态结合
android·java
大耳猫12 小时前
Android SharedFlow 详解
android·kotlin·sharedflow
火柴就是我13 小时前
升级 Android Studio 后报错 Error loading build artifacts from redirect.txt
android
androidwork14 小时前
掌握 MotionLayout:交互动画开发
android·kotlin·交互
奔跑吧 android14 小时前
【android bluetooth 协议分析 14】【HFP详解 1】【案例一: 手机侧显示来电,但车机侧没有显示来电: 讲解AT+CLCC命令】
android·hfp·aosp13·telecom·ag·hf·headsetclient
Chenyu_31015 小时前
09.MySQL内外连接
android·数据库·mysql