You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用固定/取消固定状态变更检测及回调触发问题

检测Android应用锁定任务模式(Pin/Unpin)状态变更的解决方案

核心问题说明

onLockTaskModeEntering()和onLockTaskModeExiting()这两个回调必须要求你的应用成为设备所有者或配置文件所有者(属于设备策略管理器DPM范畴)才能触发。哪怕只是接收状态变更通知,系统也只会将这类事件发送给具备设备管理权限的应用——这是Android系统对锁定任务模式这类安全管控功能的权限限制,官方文档虽未单独明确标注这两个回调的权限要求,但它们属于DeviceAdminReceiver的设备管理相关回调,默认依赖设备所有者/配置文件所有者权限。


方案一:通过DeviceAdminReceiver实现(需设备/配置文件所有者权限)

1. 配置DeviceAdminReceiver组件

在清单文件中正确声明Receiver,添加对应的intent-filter和权限:

<receiver
    android:name=".MyDeviceAdminReceiver"
    android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data
        android:name="android.app.device_admin"
        android:resource="@xml/device_admin" />
    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
        <action android:name="android.app.action.LOCK_TASK_MODE_ENTERING" />
        <action android:name="android.app.action.LOCK_TASK_MODE_EXITING" />
    </intent-filter>
</receiver>

2. 配置设备管理权限策略

在res/xml/device_admin.xml中声明需使用的设备管理策略,必须包含lock-task:

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <lock-task />
    </uses-policies>
</device-admin>

3. 将应用设置为设备所有者/配置文件所有者

通过adb命令完成权限授予:

  • 设置为设备所有者:
adb shell dpm set-device-owner com.your.package/.MyDeviceAdminReceiver
  • 设置为工作配置文件所有者(适用于多用户场景):
adb shell dpm set-profile-owner com.your.package/.MyDeviceAdminReceiver [user-id]

注意:设备所有者只能设置一个,若已有其他应用占用,需先通过adb shell dpm remove-active-admin com.other.package/.OtherAdminReceiver移除。

4. 实现回调逻辑

在自定义的MyDeviceAdminReceiver中重写回调:

public class MyDeviceAdminReceiver extends DeviceAdminReceiver {
    @Override
    public void onLockTaskModeEntering(Context context, Intent intent, String pkg) {
        super.onLockTaskModeEntering(context, intent, pkg);
        // 处理进入锁定任务模式的逻辑
    }

    @Override
    public void onLockTaskModeExiting(Context context, Intent intent) {
        super.onLockTaskModeExiting(context, intent);
        // 处理退出锁定任务模式的逻辑
    }
}

方案二:通过辅助服务(AccessibilityService)实现(无需设备所有者权限)

如果不想让应用成为设备所有者,可借助辅助服务监听窗口状态变化,间接判断锁定任务模式的状态变更:

1. 配置辅助服务组件

在清单文件中声明辅助服务:

<service
    android:name=".MyAccessibilityService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_service_config" />
</service>

2. 配置辅助服务参数

在res/xml/accessibility_service_config.xml中设置监听的事件类型:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true" />

3. 实现状态监听逻辑

在辅助服务中对比前后的锁定任务模式状态:

public class MyAccessibilityService extends AccessibilityService {
    private int lastLockTaskState = ActivityManager.LOCK_TASK_MODE_NONE;

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
            int currentState = am.getLockTaskModeState();
            if (currentState != lastLockTaskState) {
                if (currentState != ActivityManager.LOCK_TASK_MODE_NONE) {
                    // 进入锁定任务模式
                } else {
                    // 退出锁定任务模式
                }
                lastLockTaskState = currentState;
            }
        }
    }

    @Override
    public void onInterrupt() {
        // 服务中断时的处理逻辑
    }
}

注意:辅助服务需要用户手动在系统设置的「无障碍」选项中开启,这是该方案的局限性。


内容的提问来源于stack exchange,提问作者Flyview

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 07:53:27