如何识别通过代码启动的Android应用?求低CPU方案获取最近启动应用
低CPU占用获取最近启动应用方案
- 使用
UsageStatsManager替代ActivityManager.getRunningAppProcesses():
这个API是系统专为应用使用统计设计的,相比直接扫描进程,CPU占用低很多,仅在需要查询时触发统计拉取,不会持续消耗资源。- 首先声明权限:在AndroidManifest.xml中添加
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" /> - 引导用户授权:该权限属于特殊权限,需跳转到系统设置页面让用户手动开启,跳转代码示例:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivity(intent); - 查询最近启动应用的代码示例:
UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); long endTime = System.currentTimeMillis(); long startTime = endTime - 1000 * 60 * 30; // 查询最近30分钟的记录 List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_BEST, startTime, endTime); // 按最后使用时间排序,取最近的应用 if (usageStatsList != null) { Collections.sort(usageStatsList, (o1, o2) -> Long.compare(o2.getLastTimeUsed(), o1.getLastTimeUsed())); for (UsageStats stats : usageStatsList) { String packageName = stats.getPackageName(); // 处理包名,获取应用信息 } }
- 首先声明权限:在AndroidManifest.xml中添加
识别代码启动的应用方法
目前没有直接的系统API可以区分"手动启动"和"代码启动",但可以通过以下逻辑间接判断:
- 对比启动的Activity是否为应用的Launcher Activity:
- 通过
PackageManager获取应用的Launcher Activity信息:PackageManager pm = getPackageManager(); Intent launcherIntent = new Intent(Intent.ACTION_MAIN); launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER); List<ResolveInfo> resolveInfos = pm.queryIntentActivities(launcherIntent, 0); Map<String, String> launcherPackageMap = new HashMap<>(); for (ResolveInfo info : resolveInfos) { launcherPackageMap.put(info.activityInfo.packageName, info.activityInfo.name); } - 结合
UsageStatsManager的UsageEvents获取启动事件的具体Activity:UsageEvents events = usageStatsManager.queryEvents(startTime, endTime); UsageEvents.Event event = new UsageEvents.Event(); while (events.hasNextEvent()) { events.getNextEvent(event); if (event.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED) { String packageName = event.getPackageName(); String activityName = event.getClassName(); // 如果当前启动的Activity不是该应用的Launcher Activity,大概率是通过代码启动的 if (!activityName.equals(launcherPackageMap.get(packageName))) { // 标记该应用为代码启动 } } }
- 通过
- 补充判断逻辑:如果应用的启动事件来自其他应用的Intent调用,或者应用在后台被唤醒启动,也倾向于是代码启动的场景。
内容的提问来源于stack exchange,提问作者lbj
相关产品推荐
相关产品推荐

