zoukankan      html  css  js  c++  java
  • Android Disable Package/Component 跳过app安装

    1. Disable Package

    PackageManager pm = context.getPackageManager();
    pm.setApplicationEnabledSetting("com.qualcomm.location", PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);

    需要system权限以及添加

    <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />

    2. Disable Component

    PackageManager pm = context.getPackageManager();
    ComponentName name = new ComponentName(context, CryptKeeper.class);
    pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,  PackageManager.DONT_KILL_APP);

    关于第二个参数的介绍:

    /**
         * Flag for {@link #setApplicationEnabledSetting(String, int, int)}
         * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
         * component or application is in its default enabled state (as specified
         * in its manifest).
         */
        public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0;
    
        /**
         * Flag for {@link #setApplicationEnabledSetting(String, int, int)}
         * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
         * component or application has been explictily enabled, regardless of
         * what it has specified in its manifest.
         */
        public static final int COMPONENT_ENABLED_STATE_ENABLED = 1;
    
        /**
         * Flag for {@link #setApplicationEnabledSetting(String, int, int)}
         * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
         * component or application has been explicitly disabled, regardless of
         * what it has specified in its manifest.
         */
        public static final int COMPONENT_ENABLED_STATE_DISABLED = 2;
    
        /**
         * Flag for {@link #setApplicationEnabledSetting(String, int, int)} only: The
         * user has explicitly disabled the application, regardless of what it has
         * specified in its manifest.  Because this is due to the user's request,
         * they may re-enable it if desired through the appropriate system UI.  This
         * option currently <strong>can not</strong> be used with
         * {@link #setComponentEnabledSetting(ComponentName, int, int)}.
         */
        public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3;
    View Code

    在frameworks/base/services/java/com/android/server/pm/PackageManagerService.java中有下面一段代码:

            // Limit who can change which apps
            if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
                // Don't allow apps that don't have permission to modify other apps
                if (!allowedByPermission
                        || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
                    throw new SecurityException(
                            "Attempt to change component state; "
                            + "pid=" + Binder.getCallingPid()
                            + ", uid=" + callingUid
                            + (className == null
                                    ? ", package=" + packageName
                                    : ", component=" + packageName + "/" + className));
                }

    可以看出Android不让其他app来禁用另外的app。

    想让你在同一个app里操作这个应用的禁用,所以会根据你的uid,判断是不是一个app在做这个操作。 
    因此,可以看出,系统想让自身来管理自己,所以最好是在自己app中来管理自己被disable。 

    3. 在 PackageManagerService 中跳过app的安装

    PackageManagerService会在第一次启动时遍历/system/app/, /system/priv-app/, system/framework/, /vendor/app/等目录里面是否有需要安装的app,如果有jar或者apk就会把app安装被加在一个list里面。

    这样如果我们如果不想app被安装,可以根据app name来跳过当前app的安装。

    遍历和安装app的方法在 

    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {

    实际安装的方法为:

    parallelPackageParser.submit(file, parseFlags);

    所以只需要在遍历到不希望装的app时候,continue跳出这个循环,不去走parallelPackageParser.submit(), app就不会被安装

    即在这句前面加:

    if(file.getName().contains("ABCDE")) {
        Log.i("Kunkka","Skip ABCDE");
        continue;
    }           
  • 相关阅读:
    unittest框架assert断言
    python logging 总结
    好文章推荐 数据库mysql
    python 日志模块 日志格式
    django admin 后台总结(转载)
    xpath解析html标签
    lua 排序table.sort()用法
    lua 随机数 math.random()和math.randomseed()用法
    三种方法获取 lua时间戳
    crontab调用python脚本新思路
  • 原文地址:https://www.cnblogs.com/kunkka/p/9481196.html
Copyright © 2011-2022 走看看