Android packageManager.setComponentEnabledSetting()和setApplicationEnabledSetting()方法介紹

明天的增加發表於2020-11-13

1、setComponentEnabledSetting()方法

PackageManager提供了一個方法,setComponentEnabledSetting(),這個方法的作用是啟用或者禁用四大元件,比如我們想禁用一個服務,就可以使用下面的方法,傳入的引數就是服務的名稱。

/**
 * 禁用元件
 * @param context 上下文
 * @param className 元件類名
 */
private fun disableComponent(context: Context, className: String) {
    val componentName = ComponentName(context, className)
    if (isComponentDisabled(context, componentName)) return //已經禁用

    context.packageManager.setComponentEnabledSetting(
            componentName,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
    )
}

如果想重新啟用的話,也是上面的方法,只是setComponentEnabledSetting()第二個引數值不一樣,我們只需要將
PackageManager.COMPONENT_ENABLED_STATE_ENABLED替換PackageManager.COMPONENT_ENABLED_STATE_DISABLED即可。

/**
 * 啟用元件
 * @param context 上下文
 * @param className 元件類名
 */
private fun enableComponent(context: Context, className: String) {
    val componentName = ComponentName(context, className)

    if (isComponentEnabled(context, componentName)) return //已經啟用

    context.packageManager.setComponentEnabledSetting(
            componentName,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
    )
}

還有獲取元件狀態的方法,就是getComponentEnabledSetting(componentName),具體的程式碼如下,分別是獲取可用狀態和禁用狀態的方法。

/**
 * 元件是否處於可用狀態
 */
@JvmStatic
fun isComponentEnabled(context: Context, componentName: ComponentName): Boolean {
    val state: Int = context.packageManager.getComponentEnabledSetting(componentName)
    return PackageManager.COMPONENT_ENABLED_STATE_ENABLED == state
}
/**
 * 元件是否處於禁用狀態
 */
@JvmStatic
fun isComponentDisabled(context: Context, componentName: ComponentName): Boolean {
    val state: Int = context.packageManager.getComponentEnabledSetting(componentName)
    return PackageManager.COMPONENT_ENABLED_STATE_DISABLED == state
}

有了上面的方法,我們就可以無需釋出版本,就可以更換app的圖示了,我們只需要在Manifest中註冊SplashActivity的別名,然後設定對應的圖示,就可以更換app的圖示,當然從程式碼執行到更換完成還是需要幾分鐘的延遲的,這點無法避免。

<activity-alias
    android:name=".SplashAlias11Activity"
    android:enabled="false"
    android:icon="@mipmap/done"
    android:targetActivity=".SplashActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>

有了上面的別名,我們可以在啟用的時候,傳入別名即可。

enableComponent(context,"com.example.viewtest.SplashAlias11Activity")

具體更換圖示思路可以參考:https://www.jianshu.com/p/ad567861bc0e

2、setApplicationEnabledSetting()方法

setApplicationEnabledSetting()方法是PackageManager提供的禁用app的方法,一般只能用來禁用自己,不能禁用其他app,否則會報錯誤,因為系統會判斷禁用的應用uid和當前應用的uid是否一致,如果不一致,就會報錯。下面是原始碼,使用這個方法需要許可權。

/**
     * Set the enabled setting for an application
     * This setting will override any enabled state which may have been set by the application in
     * its manifest.  It also overrides the enabled state set in the manifest for any of the
     * application's components.  It does not override any enabled state set by
     * {@link #setComponentEnabledSetting} for any of the application's components.
     *
     * @param packageName The package name of the application to enable
     * @param newState The new enabled state for the application.
     * @param flags Optional behavior flags.
     */
    @RequiresPermission(value = android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE,
            conditional = true)
    public abstract void setApplicationEnabledSetting(@NonNull String packageName,
            @EnabledState int newState, @EnabledFlags int flags);

使用方法:

context.packageManager..setApplicationEnabledSetting("com.example.viewtest", PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);

其他引數介紹:
COMPONENT_ENABLED_STATE_DEFAULT:恢復元件進入預設的狀態
COMPONENT_ENABLED_STATE_ENABLED:啟用元件
COMPONENT_ENABLED_STATE_DISABLED:禁用元件
COMPONENT_ENABLED_STATE_DISABLED_USER:由使用者禁用app,所以是可以重新啟用的,只能setApplicationEnabledSetting()方法使用
COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:也是禁用app,但是使用者還是可以在介面上看到app,點選之後就會重新啟用,狀態改為enabled,只能setApplicationEnabledSetting()方法使用

相關文章