You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何检测用户打开其他应用?求App Locker类应用的应用启动事件获取方案

嘿,我来帮你拆解这两个问题——都是做App Locker这类应用的核心需求,分平台给你讲清楚:

问题1:能否检测到用户打开其他应用程序?

这个得看你针对的是Android还是iOS平台,两者的限制差异很大:

  • Android平台:可以实现,但受系统版本和权限限制。Android 10(API 29)之前,通过UsageStatsManager或辅助功能服务(AccessibilityService)能检测应用启动;Android 10及以后,系统收紧了权限,需要用户主动授予「使用情况访问权限」或开启辅助功能,且不能滥用权限(否则会被Google Play拒审)。
  • iOS平台:官方不允许。因为iOS的沙盒机制,应用只能访问自己的沙盒数据,无法监听其他应用的启动事件。除非使用私有API,但这类应用无法通过App Store审核,只能用于企业内部分发。
问题2:开发类似App Locker的应用,如何获取用户打开应用的事件?

重点说Android的实现方案(iOS基本走不通合规路线),目前主流的两种方式:

方案1:AccessibilityService(辅助功能服务,实时性最好)

这是App Locker类应用最常用的方案,能实时捕获应用切换/启动事件:

  1. 创建自定义AccessibilityService类
public class AppLockerAccessibilityService extends AccessibilityService {
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        // 监听窗口状态变化事件(应用启动/切换会触发这个事件)
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            String targetPackage = event.getPackageName().toString();
            // 判断当前启动的应用是否是你需要锁定的应用
            if (isAppNeedLock(targetPackage)) {
                // 弹出自定义的解锁界面
                launchUnlockActivity();
            }
        }
    }

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

    private boolean isAppNeedLock(String packageName) {
        // 这里写你的判断逻辑,比如对比预设的锁定应用列表
        return "com.example.targetapp".equals(packageName);
    }

    private void launchUnlockActivity() {
        Intent intent = new Intent(this, UnlockActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
}
  1. 在Manifest中注册服务
<service
    android:name=".AppLockerAccessibilityService"
    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>
  1. 配置辅助功能参数(res/xml/accessibility_service_config.xml)
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_service_desc" />
  1. 引导用户开启权限:辅助功能权限必须用户手动在系统设置中开启,你需要在应用中引导用户跳转至设置页面:
private void requestAccessibilityPermission() {
    Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
    startActivity(intent);
}

方案2:UsageStatsManager(使用情况统计服务,实时性稍差)

这个方案需要用户授予「使用情况访问权限」,适合后台周期性检测应用启动:

  1. 请求权限
private void requestUsageStatsPermission() {
    Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
    startActivity(intent);
}
  1. 查询最近启动的应用
UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
long endTime = System.currentTimeMillis();
long startTime = endTime - 1000 * 60; // 查询最近1分钟的使用记录
List<UsageStats> stats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime);

if (stats != null && !stats.isEmpty()) {
    // 按最后使用时间排序,取最近的应用
    stats.sort((a, b) -> Long.compare(b.getLastTimeUsed(), a.getLastTimeUsed()));
    String recentPackage = stats.get(0).getPackageName();
    // 这里判断是否是需要锁定的应用
    if (isAppNeedLock(recentPackage)) {
        // 触发解锁逻辑
    }
}

两种方案对比

  • AccessibilityService:实时性强,能第一时间捕获应用启动,但需要用户开启辅助功能,权限申请门槛高;
  • UsageStatsManager:权限申请相对容易接受,但只能周期性查询,实时性不足,适合后台监控。

内容的提问来源于stack exchange,提问作者Amrit Kumar Singh

火山引擎 最新活动