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;
}           

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM