Android Disable Package/Component 跳過app安裝

1. Disable Packagejava

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

須要system權限以及添加android

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

2. Disable Componentapp

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

關於第二個參數的介紹:less

/** * 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中有下面一段代碼:ide

// 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。ui

想讓你在同一個app裏操做這個應用的禁用,因此會根據你的uid,判斷是否是一個app在作這個操做。 
所以,能夠看出,系統想讓自身來管理本身,因此最好是在本身app中來管理本身被disable。 this

3. 在 PackageManagerService 中跳過app的安裝spa

PackageManagerService會在第一次啓動時遍歷/system/app/, /system/priv-app/, system/framework/, /vendor/app/等目錄裏面是否有須要安裝的app,若是有jar或者apk就會把app安裝被加在一個list裏面。code

這樣若是咱們若是不想app被安裝,能夠根據app name來跳過當前app的安裝。component

遍歷和安裝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; } 
相關文章
相關標籤/搜索