Android中如何检测目标应用是否在后台运行?原有方法失效求助
解决Android检测其他应用后台运行状态的问题
你的问题核心是Android系统权限限制导致旧方法失效:从Android 10(API 29)开始,系统收紧了隐私权限,ActivityManager.getRunningAppProcesses()只能返回当前应用的进程信息,无法再获取其他应用的进程状态,所以原来的代码只能检测自身进程。
针对你的使用场景(避免重复登录,根据目标应用状态选择启动方式),提供两种可行方案:
方案一:使用UsageStatsManager获取应用运行状态(需特殊权限)
这个方法可以准确获取其他应用的使用状态,但需要用户授权PACKAGE_USAGE_STATS权限。
步骤1:添加权限声明
在AndroidManifest.xml中添加:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
步骤2:权限检查与申请
// 检查是否已获取使用统计权限 fun hasUsageStatsPermission(context: Context): Boolean { val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager val mode = appOps.checkOpNoThrow( AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), context.packageName ) return mode == AppOpsManager.MODE_ALLOWED } // 引导用户开启权限 fun requestUsageStatsPermission(context: Context) { val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent) }
步骤3:检测应用是否在后台运行
fun isTargetAppRunning(context: Context, targetPackage: String): Boolean { val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager val currentTime = System.currentTimeMillis() // 查询最近5分钟的应用使用统计(可根据需求调整时间范围) val stats = usageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_BEST, currentTime - 5 * 60 * 1000, currentTime ) stats?.forEach { usageStat -> if (usageStat.packageName == targetPackage && usageStat.lastTimeUsed > currentTime - 1000) { // 目标应用在最近1秒内有活跃记录,判定为后台运行 return true } } return false }
方案二:绕过状态检测,在目标应用内处理登录逻辑(更推荐)
如果你的目标应用是可控的(自己开发的),可以直接在目标应用的启动页处理登录判断,无需在源应用中检测状态,这种方式不需要额外权限,更稳定。
在目标应用的启动Activity中添加逻辑:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 先判断用户是否已登录 if (isUserLoggedIn()) { // 已登录直接跳转到主页面,跳过登录流程 startActivity(Intent(this, MainActivity::class.java)) finish() return } // 未登录时,处理源应用传递的登录参数 val needLogin = intent.getBooleanExtra("need_login", false) if (needLogin) { // 执行登录流程 startLoginFlow() } } // 模拟判断用户登录状态的方法 private fun isUserLoggedIn(): Boolean { return SharedPreferences.getDefaultSharedPreferences(this) .getBoolean("is_logged_in", false) }
此时,源应用只需统一携带登录Intent启动目标应用即可:
fun launchTargetApp(context: Context, targetPackage: String) { val launchIntent = context.packageManager.getLaunchIntentForPackage(targetPackage) ?: return launchIntent.putExtra("need_login", true) launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(launchIntent) }
目标应用会自动判断是否需要执行登录,完全避免重复登录的问题。
内容的提问来源于stack exchange,提问作者Wesley DaBes
相关产品推荐
相关产品推荐

