android怎样判断应用程序退到后台

判断手机是否退到后台,这是我们在Android开发中实现一些功能时,经常会考虑的问题,比如:按HOME,BACK键时,程序退到后台,消息以Notification形式弹出 ,或者程序在服务中把App退到后台,弹出服务浮窗,点击后回到当前页面等,这些也是实现及时通讯,服务推送过程经常遇到的,比如QQ,微信消息提醒,网络电话通知展示等.

废话不多说,直接上图:


如果需要判断程序进入后台,然后显示通知,弹出通知之后,直接进入HOME键之前页面,情点击下一节

程序后台切换前台,点击通知进入当前页面

DEMO下载地址为:点击下载demo


判断手机是否退到后台,本人查阅各种资料,发现实现其实很简单,目前自己主要实现方式有两种:
方式一:
 
   
  1. /**
  2. * 程序是否在前台运行
  3. *
  4. */
  5. public boolean isAppOnForeground() {
  6. ActivityManager activityManager = (ActivityManager) getApplicationContext()
  7. .getSystemService(Context.ACTIVITY_SERVICE);
  8. String packageName = getApplicationContext().getPackageName();
  9. /**
  10. * 获取Android设备中所有正在运行的App
  11. */
  12. List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager
  13. .getRunningAppProcesses();
  14. if (appProcesses == null)
  15. return false;
  16. for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
  17. // The name of the process that this object is associated with.
  18. if (appProcess.processName.equals(packageName)
  19. && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
  20. return true;
  21. }
  22. }
  23. return false;
  24. }
这是我在网上找到的例子,主要的实现原理就是,使用 ActivityManager,首先 拿到自己App的包名,再拿到Android设备中所有正在运行的App包名,然后对所有的App进行遍历,通过判断正在运行的App中包名有没有和自己的App相等,从而判断自己的App是否退到后台.
 
   
  1. @Override
  2. protected void onPause() {
  3. super.onPause();
  4. if(!isAppOnForeground()){
  5. Toast.makeText(getApplicationContext(), TAG+"onPause:",
  6. Toast.LENGTH_SHORT).show();
  7. }else {
  8. sendBroadcast(new Intent(NotificationIntentReceiver.ACTION_ENABLE_MESSAGES)
  9. .setClass(this, NotificationIntentReceiver.class));
  10. Toast.makeText(getApplicationContext(), TAG+"后台运行1",
  11. Toast.LENGTH_SHORT).show();
  12. }
  13. }

然后在onPause()方法中,进行判断,上面代码中实现的是,App退出后台就发送广播,然后在广播中执行Notification,然后在回到Activity时,在onResume()中清除应该清除Notification.

方法二:
这种方法主要是根据Application中 实现 ActivityLifecycleCallbacks 回调 , ActivityLifecycleCallbacks是4.0以后新增的,主要用于监听Activity的状态, 这里主要关注onActivityStarted(Activity activity)和onActivityStopped(Activity activity)两个方法,简单的解释:Activity在start时会走onActivity Started方法,而 Activity在退出后台时,则会走 onActivityStopped方法,所以我们可以通过这种方法实现:

 
   
  1. int countActivity = 0;
 
   
  1. @Override
  2. public void onActivityStarted(Activity activity) {
  3. countActivity++;
  4. }
 
    
  1. @Override
  2. public void onActivityStopped(Activity activity) {
  3. countActivity--;
  4. L.i("onActivityStopped", "countActivity=" + countActivity);
  5. if (countActivity <= 0) {
  6. if (WDRTCSysConfig.getInstance().isCalling()) {
  7. Intent _intent = new Intent(WDBroadcastReceiver.ACTION_ENABLE_MESSAGES);
  8. _intent.setClass(getApplicationContext(), WDBroadcastReceiver.class);
  9. sendBroadcast(_intent);
  10. }
  11. }
  12. }
上面的代码主要原理是:我在自定义的Application中定义一个变量,主要是模拟 Stack<Activity>判断等操作, 当我们 一个 Activity在 Start时countActivity就加一,当我们 一个 Activity在 Stop时 countActivity就减一,而最后当我们 countActivity值等于0时,就代表App没有Activity正在Start,程序在退到后台,然后执行我们需要执行的退到后台处理, WDRTCSysConfig . getInstance (). isCalling () 只是一个布尔值得逻辑判断,我这里执行的是正在语音服务中,APP退到后台是,发生广播,执行通知的操作.
ActivityLifecycleCallbacks的实现重写的方法如下:
 
   
  1. public class DemoApplication extends Application implements Application.ActivityLifecycleCallbacks{
  2. @Override
  3. public void onCreate() {
  4. super.onCreate();
  5. //全局管理Activity生命周期
  6. registerActivityLifecycleCallbacks(this);
  7. }
  8. @Override
  9. public void onActivityCreated(Activity activity, Bundle bundle) {
  10. }
  11. @Override
  12. public void onActivityStarted(Activity activity) {
  13. }
  14. @Override
  15. public void onActivityResumed(Activity activity) {
  16. }
  17. @Override
  18. public void onActivityPaused(Activity activity) {
  19. }
  20. @Override
  21. public void onActivityStopped(Activity activity) {
  22. }
  23. @Override
  24. public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
  25. }
  26. @Override
  27. public void onActivityDestroyed(Activity activity) {
  28. }

那么问题来了 应用退出和应用进入 这两个事件 如何过滤掉呢

/**
     * 判断应用是否在运行
     * @param context
     * @return
     */
    public boolean isRun(Context context){
        ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> list = am.getRunningTasks(100);
        boolean isAppRunning = false;
        String MY_PKG_NAME = "com.ad";
        //100表示取的最大的任务数,info.topActivity表示当前正在运行的Activity,info.baseActivity表系统后台有此进程在运行
        for (RunningTaskInfo info : list) {
            if (info.topActivity.getPackageName().equals(MY_PKG_NAME) || info.baseActivity.getPackageName().equals(MY_PKG_NAME)) {
                isAppRunning = true;
                Log.i("ActivityService isRun()",info.topActivity.getPackageName() + " info.baseActivity.getPackageName()="+info.baseActivity.getPackageName());
                break;
            }
        }
        
        Log.i("ActivityService isRun()", "com.ad 程序   ...isAppRunning......"+isAppRunning);
        return isAppRunning;
    }

再用上这个工具类就可以了 完整代码我贴一下

 private int countActivity = 0;
    //是否进入后台
    private boolean isBackground=false;
//全局管理 生命周期
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

            }

            @Override
            public void onActivityStarted(Activity activity) {
                countActivity++;
                if(countActivity==1&& isBackground){
                    Log.e(TAG, "onActivityStarted: 应用进入前台" );
                    isBackground=false;
                    //说明应用重新进入了前台
                 
                }
            }

            @Override
            public void onActivityResumed(Activity activity) {

            }

            @Override
            public void onActivityPaused(Activity activity) {


            }


            @Override
            public void onActivityStopped(Activity activity) {
                countActivity--;
                LogUtils.e(TAG, "onActivityStarted: "+isRun(activity));
                if (countActivity <= 0&&!isBackground&&isRun(activity)) {
                    Log.e(TAG, "onActivityStarted: 应用进入后" );
                    isBackground =true;
                    //说明应用进入了后台
                   
                }
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        });


    }



猜你喜欢

转载自blog.csdn.net/mp624183768/article/details/80940801