Android 和setApplicationEnabledSetting方法介绍

时间:2025-01-25 12:55:11

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 //已经禁用

    (
            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 //已经启用

    (
            componentName,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
    )
}

还有获取组件状态的方法,就是getComponentEnabledSetting(componentName),具体的代码如下,分别是获取可用状态和禁用状态的方法。

/**
 * 组件是否处于可用状态
 */
@JvmStatic
fun isComponentEnabled(context: Context, componentName: ComponentName): Boolean {
    val state: Int = (componentName)
    return PackageManager.COMPONENT_ENABLED_STATE_ENABLED == state
}
/**
 * 组件是否处于禁用状态
 */
@JvmStatic
fun isComponentDisabled(context: Context, componentName: ComponentName): Boolean {
    val state: Int = (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="" />
        <category android:name="" />
    </intent-filter>
</activity-alias>

有了上面的别名,我们可以在启用的时候,传入别名即可。

enableComponent(context,".SplashAlias11Activity")

具体更换图标思路可以参考:双11快到了,不给你的APP加上自动换图标的功能吗? - 简书双11快到了,不给你的APP加上自动换图标的功能吗? - 简书双11快到了,不给你的APP加上自动换图标的功能吗? - 简书

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 = .CHANGE_COMPONENT_ENABLED_STATE,
            conditional = true)
    public abstract void setApplicationEnabledSetting(@NonNull String packageName,
            @EnabledState int newState, @EnabledFlags int flags);

使用方法:

..setApplicationEnabledSetting("", PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);

其他参数介绍:
COMPONENT_ENABLED_STATE_DEFAULT:0 恢复组件进入默认的状态
COMPONENT_ENABLED_STATE_ENABLED:1 启用组件
COMPONENT_ENABLED_STATE_DISABLED:2 禁用组件
COMPONENT_ENABLED_STATE_DISABLED_USER:3 由用户禁用app,所以是可以重新启用的,只能setApplicationEnabledSetting()方法使用
COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:4 也是禁用app,但是使用者还是可以在界面上看到app,点击之后就会重新启用,状态改为enabled,只能setApplicationEnabledSetting()方法使用

原文链接:/StudyOfAndroid/article/details/109678471