当前位置: 首页 > article >正文

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

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

1. 静态注册广播

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

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. 收到广播后设置全局变量

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

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. 卸载时不做处理

在设置-应用中卸载

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拖动不显示卸载

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;

http://www.kler.cn/a/538726.html

相关文章:

  • 【Python】元组
  • C++ 设计模式 - 访问者模式
  • Goland 内存逃逸问题
  • 【redis】数据类型之hash
  • 【自学笔记】文言一心的基础知识点总览-持续更新
  • 基于DeepSeek API和VSCode的自动化网页生成流程
  • ES管理器焕新升级:紫色银狼主题来袭!
  • 在 Navicat 17 中扩展 PostgreSQL 数据类型 | 复合类型
  • 教育机器人的智能驱动:揭秘舵机技术的无限可能
  • 使用Python和TensorFlow/Keras构建一个简单的CNN模型来识别手写数字
  • 系统URL整合系列视频五(后端技术实现)
  • Android Studio 配置 Gerrit Code Review
  • 深入Linux系列之环境变量
  • ZZNUOJ(C/C++)基础练习1081——1090(详解版)
  • k8s中pod常见状态解析
  • go结构体和json相互转换、序列化和反序列化
  • 2025年日祭
  • Linux strace命令介绍
  • 音频知识基础
  • 神经网络常见激活函数 5-PReLU函数
  • 阿里云专有云网络架构学习
  • 金三银四Java面试题及答案整理(2025年最新版,持续更新)
  • Java进阶面试八股文
  • DeepSeek使用技巧大全(含本地部署教程)
  • Vue 3 部分新特性解析
  • 【Unity】从父对象中获取子对象组件的方式