博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
判断你的应用在前台还是在后台
阅读量:5273 次
发布时间:2019-06-14

本文共 5156 字,大约阅读时间需要 17 分钟。

我的尝试

/**     * 判断应用是否是在后台     */    public static boolean isBackground(Context context) { ActivityManager activityManager = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE); List
appProcesses = activityManager .getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { if (TextUtils.equals(appProcess.processName, context.getPackageName())) { return appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; } } return false; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

一开始我用这个方法用来判断手机是否处于后台状态,如果应用处于后台的话,就停止应用程序中的音乐播放,但是却发现,点击 Home 键让应用退到后台并不会让音乐停止播放,后来发现如果应用正在播放音乐的话,此时点击 Home 键应用并不会进入后台状态( ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND ),而是进入了一个 ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE 的状态, 这个状态正是系统提供的应用后台播放应用的状态,好了,我们继续在原来的代码上进行完善:

/**     * 判断应用是否是在后台     */    public static boolean isBackground(Context context) { ActivityManager activityManager = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE); List
appProcesses = activityManager .getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { if (TextUtils.equals(appProcess.processName, context.getPackageName())) { return (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND || appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE); } } return false; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这样即使应用在播放应用的时候点击 Home 键也可以认为此时处于后台状态,但是此时依然会出现判断应用是否在后台不准确的情况,我们继续优化原来的代码。

/**     * 判断应用是否是在后台     */    public static boolean isBackground(Context context) { ActivityManager activityManager = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE); List
appProcesses = activityManager .getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { if (TextUtils.equals(appProcess.processName, context.getPackageName())) { boolean isBackground = (appProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE); boolean isLockedState = keyguardManager.inKeyguardRestrictedInputMode(); return isBackground || isLockedState; } } return false; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

上面这个方法通过监测应用进程是否处于前台状态,是否可见,手机是否锁屏来判断应用是否处于前台,如果这些情况有任一条达成的话就表明应用没有处于前台状态,这个方法在大部分机上都没有发现异常,但是我却在原生的 Nexus 5 手机上发现当当栈中的Activiy只有一个 Activity的时候,例如:应用启动,SplashActivity启动LoginActivity后,关闭SplashActivity,此时栈中就只生剩下了LoginActivity,此时,无论是点击返回键退出、点击 Home 键退到后台甚至点击右侧的多进程按键,此时的appProcess.importance 的都为 ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND,这样就彻底宣告了判断 appProcess.importance方法的失败。

最终用法

继承 Application.ActivityLifecycleCallbacks 写一个自己的 ActivityLifecycleCallbacks:

public class MyLifecycleHandler implements Application.ActivityLifecycleCallbacks { private static int resumed; private static int paused; private static int started; private static int stopped; @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { ++started; } @Override public void onActivityResumed(Activity activity) { ++resumed; } @Override public void onActivityPaused(Activity activity) { ++paused; android.util.Log.w("test", "application is in foreground: " + (resumed > paused)); } @Override public void onActivityStopped(Activity activity) { ++stopped; android.util.Log.w("test", "application is visible: " + (started > stopped)); } @Override public void onActivityDestroyed(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } public static boolean isApplicationVisible() { return started > stopped; } public static boolean isApplicationInForeground() { // 当所有 Activity 的状态中处于 resumed 的大于 paused 状态的,即可认为有Activity处于前台状态中 return resumed > paused; } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

然后在自己定义的 Application 中的 onCreate() 方法中注册该 ActivityLifecycleCallbacks:

registerActivityLifecycleCallbacks(new MyLifecycleHandler());
  • 1
  • 1

这样的话我们就可以在自己定义的 ActivityLifecycleCallbacks 中监控自己应用中的所有的 Activity 的状态,通过 MyLifecycleHandler.isApplicationInForeground() 方法即可判断应用此时一定处于前台状态中,反之,则是处于”后台状态”。

以上就是我对于当前应用是处于前台还是后台的判断,无论大家是发现BUG和改进,还是有其它更好的办法,欢迎前来讨论!

需要注意:ActivityLifecycleCallbacks是在 API 14 即  4.0加入的。

参考链接

 

 
 

 
 

转载于:https://www.cnblogs.com/dongweiq/p/7027585.html

你可能感兴趣的文章
java equals 小记
查看>>
2019春 软件工程实践 助教总结
查看>>
Zerver是一个C#开发的Nginx+PHP+Mysql+memcached+redis绿色集成开发环境
查看>>
程序的静态链接,动态链接和装载 (补充)
查看>>
关于本博客说明
查看>>
[Kaggle] Sentiment Analysis on Movie Reviews
查看>>
价值观
查看>>
mongodb命令----批量更改文档字段名
查看>>
国外常见互联网盈利创新模式
查看>>
android:scaleType属性
查看>>
shell脚本
查看>>
Upload Image to .NET Core 2.1 API
查看>>
【雷电】源代码分析(二)-- 进入游戏攻击
查看>>
Linux中防火墙centos
查看>>
如何设置映射网络驱动器的具体步骤和方法
查看>>
centos下同时启动多个tomcat
查看>>
Leetcode Balanced Binary Tree
查看>>
[JS]递归对象或数组
查看>>
linux sed命令
查看>>
湖南多校对抗赛(2015.03.28) H SG Value
查看>>