{"id":13989402,"url":"https://github.com/wenmingvs/AndroidProcess","last_synced_at":"2025-07-22T10:32:18.422Z","repository":{"id":41113823,"uuid":"49931624","full_name":"wenmingvs/AndroidProcess","owner":"wenmingvs","description":"判断App位于前台或者后台的6种方法","archived":false,"fork":false,"pushed_at":"2022-09-09T12:42:48.000Z","size":11122,"stargazers_count":2769,"open_issues_count":16,"forks_count":504,"subscribers_count":94,"default_branch":"master","last_synced_at":"2024-04-07T15:36:03.971Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wenmingvs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-01-19T06:28:11.000Z","updated_at":"2024-04-06T14:16:52.000Z","dependencies_parsed_at":"2023-01-18T02:15:41.623Z","dependency_job_id":null,"html_url":"https://github.com/wenmingvs/AndroidProcess","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wenmingvs%2FAndroidProcess","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wenmingvs%2FAndroidProcess/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wenmingvs%2FAndroidProcess/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wenmingvs%2FAndroidProcess/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wenmingvs","download_url":"https://codeload.github.com/wenmingvs/AndroidProcess/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":214668076,"owners_count":15767088,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-09T13:01:38.146Z","updated_at":"2024-08-09T13:06:54.844Z","avatar_url":"https://github.com/wenmingvs.png","language":"Java","funding_links":[],"categories":["Java","Libs","Utility"],"sub_categories":["\u003cA NAME=\"Utility\"\u003e\u003c/A\u003eUtility"],"readme":"# AndroidProcess\n\n提供6种方法来判断App处于前台还是后台，并且封装成工具类供大家使用\n\n最后一种方法堪称Android黑科技（非原创），既可以突破Android5.0以上的权限封锁，获取任意前台App的包名，又不需要权限，此方法并非我原创，原作者是国外的大神，[GitHub项目在这里](https://github.com/jaredrummler/AndroidProcesses)，也一并加入到工程中，供大家做全面的参考选择   \n\n\n**2016.2.11更新------感谢[@EffectiveMatrix](http://weibo.com/hatewx?refer_flag=1005050005_)大神带来的新的判断前后台的方法**  \n\n快速下载体验\n-----\n[百度网盘](https://github.com/wenmingvs/AndroidProcess/blob/master/demo.apk)\n\n预览图\n-----\n![enter image description here](http://ww2.sinaimg.cn/large/691cc151gw1f09z4gz35mg20bc0h01kx.gif)\n\n\n\n\n用法\n-----\n传入Context参数与想要判断是否位于前台的App的包名,会返回ture或者false表示App是否位于前台\n\n``` java\n\n//六种方法任选其一\n\n//使用方法一\nBoolean isForeground = BackgroundUtil.getRunningTask(context, packageName);\n//使用方法二\nBoolean isForeground = BackgroundUtil.getRunningAppProcesses(context, packageName);\n//使用方法三\nBoolean isForeground = BackgroundUtil.getApplicationValue(context);\n//使用方法四\nBoolean isForeground = BackgroundUtil.queryUsageStats(context, packageName);\n//使用方法五\nBoolean isForeground = BackgroundUtil.getFromAccessibilityService(context, packageName);\n//使用方法六\nBoolean isForeground = BackgroundUtil.getLinuxCoreInfo(context, packageName);\n```\n\n六种方法的区别\n-----\n|方法|判断原理|需要权限|可以判断其他应用位于前台|特点\n| ------ | ------ | ------ | ------ | ------ |\n|方法一|RunningTask|否|Android4.0系列可以,5.0以上机器不行|5.0此方法被废弃\n|方法二|RunningProcess|否|当App存在后台常驻的Service时失效|无\n|方法三|ActivityLifecycleCallbacks|否|否|简单有效,代码最少\n|方法四|UsageStatsManager|是|是|需要用户手动授权\n|方法五|通过Android无障碍功能实现|否|是|需要用户手动授权\n|方法六|读取/proc目录下的信息|否|是|当proc目录下文件夹过多时,过多的IO操作会引起耗时\n\n\n方法一：通过RunningTask\n-----\n\n![enter image description here](http://ww2.sinaimg.cn/large/691cc151gw1f09z4gz35mg20bc0h01kx.gif)\n\n**原理**  \n当一个App处于前台的时候，会处于RunningTask的这个栈的栈顶，所以我们可以取出RunningTask的栈顶的任务进程，看他与我们的想要判断的App的包名是否相同，来达到效果\n\n**缺点**    \ngetRunningTask方法在Android5.0以上已经被废弃，只会返回自己和系统的一些不敏感的task，不再返回其他应用的task，用此方法来判断自身App是否处于后台，仍然是有效的，但是无法判断其他应用是否位于前台，因为不再能获取信息\n\n \n方法二：通过RunningProcess\n-----\n\n![enter image description here](http://ww1.sinaimg.cn/mw690/691cc151gw1f09z4vmmcgg20bc0h07wh.gif)\n\n**原理**  \n通过runningProcess获取到一个当前正在运行的进程的List，我们遍历这个List中的每一个进程，判断这个进程的一个importance 属性是否是前台进程，并且包名是否与我们判断的APP的包名一样，如果这两个条件都符合，那么这个App就处于前台\n\n**缺点**：  \n在聊天类型的App中，常常需要常驻后台来不间断的获取服务器的消息，这就需要我们把Service设置成START_STICKY，kill 后会被重启（等待5秒左右）来保证Service常驻后台。如果Service设置了这个属性，这个App的进程就会被判断是前台，代码上的表现就是appProcess.importance的值永远是 ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND，这样就永远无法判断出到底哪个是前台了。\n\n方法三：通过ActivityLifecycleCallbacks\n------\n\n![enter image description here](http://ww2.sinaimg.cn/mw690/691cc151gw1f09z59b1pzg20bc0h04qp.gif)\n\n**原理**  \nAndroidSDK14在Application类里增加了ActivityLifecycleCallbacks，我们可以通过这个Callback拿到App所有Activity的生命周期回调。\n``` java\n public interface ActivityLifecycleCallbacks {\n        void onActivityCreated(Activity activity, Bundle savedInstanceState);\n        void onActivityStarted(Activity activity);\n        void onActivityResumed(Activity activity);\n        void onActivityPaused(Activity activity);\n        void onActivityStopped(Activity activity);\n        void onActivitySaveInstanceState(Activity activity, Bundle outState);\n        void onActivityDestroyed(Activity activity);\n    }\n```\n知道这些信息，我们就可以用更官方的办法来解决问题，当然还是利用方案二里的Activity生命周期的特性，我们只需要在Application的onCreate()里去注册上述接口，然后由Activity回调回来运行状态即可。\n\n可能还有人在纠结，我用back键切到后台和用Home键切到后台，一样吗？以上方法适用吗？在Android应用开发中一般认为back键是可以捕获的，而Home键是不能捕获的（除非修改framework）,但是上述方法从Activity生命周期着手解决问题，虽然这两种方式的Activity生命周期并不相同，但是二者都会执行onStop（）；所以并不关心到底是触发了哪个键切入后台的。另外,Application是否被销毁,都不会影响判断的正确性\n\n方法四:通过使用UsageStatsManager获取\n-----\n![enter image description here](http://ww1.sinaimg.cn/mw690/691cc151gw1f09z5v4g7mg20bc0h0npd.gif)\n\n**原理**  \n通过使用UsageStatsManager获取，此方法是Android5.0之后提供的新API，可以获取一个时间段内的应用统计信息，但是必须满足一下要求\n\n**使用前提**  \n  1. 此方法只在android5.0以上有效 \n  2. AndroidManifest中加入此权限 \n```  java\n\u003cuses-permission  android:name=\"android.permission.PACKAGE_USAGE_STATS\" /\u003e\n```\n  3. 打开手机设置，点击安全-高级，在有权查看使用情况的应用中，为这个App打上勾\n\n![enter image description here](https://raw.githubusercontent.com/wenmingvs/AndroidProcess/master/sample/3.PNG)\n\n方法五：通过Android自带的无障碍功能\n------\n\n非常感谢[@EffectiveMatrix](http://weibo.com/hatewx?refer_flag=1005050005_)大神带来的新的判断前后台的方法  \n\n此方法属于他原创，具体的博文参照这里http://effmx.com/articles/tong-guo-android-fu-zhu-gong-neng-accessibility-service-jian-ce-ren-yi-qian-tai-jie-mian/  \n\n此方法无法直观的通过下拉通知视图来进行前后台的观察，请到LogCat中进行观察即可，以下是LogCat中打印的信息\n\n![enter image description here](http://ww3.sinaimg.cn/large/691cc151gw1f0uiy60md3j20fs07omzj.jpg)  \n \n**原理**  \nAndroid 辅助功能(AccessibilityService) 为我们提供了一系列的事件回调，帮助我们指示一些用户界面的状态变化。 我们可以派生辅助功能类，进而对不同的 AccessibilityEvent 进行处理。 同样的，这个服务就可以用来判断当前的前台应用\n\n**优势**  \n1. AccessibilityService 有非常广泛的 ROM 覆盖，特别是非国产手机，从 Android API Level 8(Android 2.2) 到 Android Api Level 23(Android 6.0)  \n2.  AccessibilityService 不再需要轮询的判断当前的应用是不是在前台，系统会在窗口状态发生变化的时候主动回调，耗时和资源消耗都极小  \n3. 不需要权限请求  \n4. 它是一个稳定的方法，与 “方法6”读取 /proc 目录不同，它并非利用 Android 一些设计上的漏洞，可以长期使用的可能很大  \n5. 可以用来判断任意应用甚至 Activity, PopupWindow, Dialog 对象是否处于前台  \n\n**劣势**  \n1. 需要要用户开启辅助功能  \n2. 辅助功能会伴随应用被“强行停止”而剥夺  \n\n方法六：读取Linux系统内核保存在/proc目录下的process进程信息\n----\n![enter image description here](http://ww3.sinaimg.cn/mw690/691cc151gw1f09z6bjz9rg20bc0h0b29.gif)\n\n此方法并非我原创，原作者是国外的大神，[GitHub项目在这里](https://github.com/jaredrummler/AndroidProcesses)，也一并加入到工程中，供大家做全面的参考选择\n\n**原理**  \n无意中看到乌云上有人提的一个漏洞，Linux系统内核会把process进程信息保存在/proc目录下，Shell命令去获取的他，再根据进程的属性判断是否为前台\n\n**优点**  \n1. 不需要任何权限  \n2. 可以判断任意一个应用是否在前台，而不局限在自身应用\n\n**缺点**  \n1. 当/proc下文件夹过多时,此方法是耗时操作\n\n**用法**  \n获取一系列正在运行的App的进程\n``` java\nList\u003cAndroidAppProcess\u003e processes = ProcessManager.getRunningAppProcesses();\n```\n\n获取任一正在运行的App进程的详细信息\n``` java\nAndroidAppProcess process = processes.get(location);\nString processName = process.name;\n\nStat stat = process.stat();\nint pid = stat.getPid();\nint parentProcessId = stat.ppid();\nlong startTime = stat.stime();\nint policy = stat.policy();\nchar state = stat.state();\n\nStatm statm = process.statm();\nlong totalSizeOfProcess = statm.getSize();\nlong residentSetSize = statm.getResidentSetSize();\n\nPackageInfo packageInfo = process.getPackageInfo(context, 0);\nString appName = packageInfo.applicationInfo.loadLabel(pm).toString();\n```\n\n判断是否在前台\n``` java\nif (ProcessManager.isMyProcessInTheForeground()) {\n  // do stuff\n}\n```\n\n获取一系列正在运行的App进程的详细信息\n``` java\nList\u003cActivityManager.RunningAppProcessInfo\u003e processes = ProcessManager.getRunningAppProcessInfo(ctx);\n```\n\nGradle 构建\n------\n- 版本\n\t- 最新 Android SDK\n\t- 最新 Gradle\n- 环境变量\n\t- ANDROID_HOME\n\t- GRADLE_HOME，同时把bin放入path变量\n\t- Android SDK 安装，都更新到最新\n\t- Android SDK Build-tools更新到最新\n\t- Google Repository更新到最新\n\t- Android Support Repository更新到最新\n\t- Android Support Library更新到最新\n\n\n相信未来\n-----\n当蜘蛛网无情地查封了我的炉台   \n当灰烬的余烟叹息着贫困的悲哀   \n我依然固执地铺平失望的灰烬   \n用美丽的雪花写下：相信未来   \n\n当我的紫葡萄化为深秋的露水   \n当我的鲜花依偎在别人的情怀   \n我依然固执地用凝霜的枯藤   \n在凄凉的大地上写下：相信未来   \n\n我要用手指那涌向天边的排浪  \n我要用手掌那托住太阳的大海  \n摇曳着曙光那枝温暖漂亮的笔杆   \n用孩子的笔体写下：相信未来   \n\n我之所以坚定地相信未来  \n是我相信未来人们的眼睛  \n她有拨开历史风尘的睫毛  \n她有看透岁月篇章的瞳孔  \n\n不管人们对于我们腐烂的皮肉  \n那些迷途的惆怅、失败的苦痛  \n是寄予感动的热泪、深切的同情   \n还是给以轻蔑的微笑、辛辣的嘲讽   \n\n我坚信人们对于我们的脊骨  \n那无数次的探索、迷途、失败和成功   \n一定会给予热情、客观、公正的评定   \n是的，我焦急地等待着他们的评定  \n\n朋友，坚定地相信未来吧  \n相信不屈不挠的努力  \n相信战胜死亡的年轻  \n相信未来、热爱生命  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwenmingvs%2FAndroidProcess","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwenmingvs%2FAndroidProcess","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwenmingvs%2FAndroidProcess/lists"}