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

Android新API下如何识别当前Activity的包名?旧方案已废弃

我太懂你这种困扰了——五六年前的老方法在新Android API下基本都废了,但既然AppBlock、AppLocker这类应用还能在Play商店好好跑着,说明肯定有适配新系统的靠谱方案。下面我就结合Android 12+的规范,给你拆解具体的实现思路:

一、检测应用启动(Android 12+适配方案)

目前最可靠的实现方式是借助**辅助功能(AccessibilityService)**监听窗口状态变化,这也是Play商店里同类应用的核心方案:

  • 核心逻辑:在自定义的AccessibilityService中重写onAccessibilityEvent方法,捕获TYPE_WINDOW_STATE_CHANGED事件,通过event.getPackageName()获取当前前台应用的包名,对比之前记录的包名就能判断是否有新应用启动。
  • 权限要求:必须申请android.permission.BIND_ACCESSIBILITY_SERVICE权限,并且需要引导用户到系统设置中手动开启你的应用的辅助功能(这是这类应用的常规操作,比如AppBlock就是这么引导用户的)。
  • 代码示例:
public class AppMonitorService extends AccessibilityService {
    private String lastForegroundPackage;

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            String currentPackage = event.getPackageName().toString();
            // 对比上次记录的包名,判断是否为新应用启动
            if (lastForegroundPackage == null || !currentPackage.equals(lastForegroundPackage)) {
                // 这里处理应用启动的逻辑,比如记录日志、触发PIN锁浮层
                lastForegroundPackage = currentPackage;
            }
        }
    }

    @Override
    public void onInterrupt() {
        // 服务被中断时的处理逻辑
    }
}
  • 辅助验证方案:可以搭配UsageStatsManager补全盲区(比如某些特殊场景下窗口事件没触发),需要申请android.permission.PACKAGE_USAGE_STATS权限,引导用户到应用使用统计设置页面授权,通过queryUsageStats获取历史使用记录来验证前台应用。
二、检测返回主页操作

返回主页本质是切换到系统Launcher应用,所以同样可以用AccessibilityService实现:

  • 核心逻辑:先获取系统默认Launcher的包名,然后在窗口切换事件中判断当前包名是否等于Launcher包名,若是则判定用户返回了主页。
  • 代码示例:
private String getSystemLauncherPackage(Context context) {
    Intent homeIntent = new Intent(Intent.ACTION_MAIN);
    homeIntent.addCategory(Intent.CATEGORY_HOME);
    ResolveInfo resolveInfo = context.getPackageManager()
            .resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
    return resolveInfo.activityInfo.packageName;
}

onAccessibilityEvent中加入判断:

String launcherPackage = getSystemLauncherPackage(this);
if (currentPackage.equals(launcherPackage)) {
    // 用户返回了主页,执行对应逻辑
}
三、AppLocker风格的PIN锁浮层实现

要在应用启动时弹出PIN锁浮层,需要借助WindowManager创建悬浮窗,适配Android 12+的权限要求:

  • 权限要求:申请android.permission.SYSTEM_ALERT_WINDOW权限,Android 10+需要引导用户到设置页面开启“显示在其他应用上层”权限。
  • 实现步骤:
    1. 当检测到目标应用启动时,通过LayoutInflater加载PIN锁布局。
    2. 配置WindowManager.LayoutParams,设置typeTYPE_APPLICATION_OVERLAY(Android 8+推荐),确保浮层能覆盖在目标应用之上。
    3. 添加PIN验证逻辑,验证通过后移除浮层,允许用户操作应用;验证失败则保持浮层显示。
  • 简化版代码示例:
private void showPinLockOverlay(Context context) {
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    View pinLockView = LayoutInflater.from(context).inflate(R.layout.layout_pin_lock, null);

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
            PixelFormat.TRANSLUCENT
    );
    params.gravity = Gravity.CENTER;
    windowManager.addView(pinLockView, params);

    // 这里添加PIN输入验证逻辑,验证通过后移除浮层
    // windowManager.removeView(pinLockView);
}
  • 注意事项:要处理屏幕旋转、多窗口模式下的浮层适配,避免出现错位或失效的情况。
四、关键权限的引导逻辑

这类应用的权限都是需要用户手动授权的,一定要做友好的引导:

  • 辅助功能权限:跳转到Settings.ACTION_ACCESSIBILITY_SETTINGS页面引导用户开启。
  • 悬浮窗权限:跳转到Settings.ACTION_MANAGE_OVERLAY_PERMISSION页面引导用户授权。
  • 应用使用统计权限:跳转到Settings.ACTION_USAGE_ACCESS_SETTINGS页面引导用户开启。

这些方案都是目前Play商店中同类应用的主流实现方式,完全适配Android 12及以上的API规范,你可以根据自己的需求组合调整。

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

火山引擎 最新活动