Android之判断前后台运行

[java] view plaincopy
  1. /** 
  2.  * 程序前后判断 
  3.  * @return 
  4.  */  
  5. private boolean isAppOnForeground() {     
  6.     ActivityManager activityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);    
  7.     String packageName = this.getPackageName();  
  8.        List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();     
  9.        if (appProcesses == null)   
  10.         return false;     
  11.        for (RunningAppProcessInfo appProcess : appProcesses) {     
  12.            if (appProcess.processName.equals(packageName)     
  13.                    && appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {     
  14.                return true;     
  15.            }     
  16.        }     
  17.        return false;     
  18.    }     


经过测试,在一般情况下可行,在某些经过简洁版本的Android系统中 RunningAppProcessInfo.importance的值一直为400,原因未找到,RunningAppProcessInfo 里面的变量importance其实是表示这个app进程的重要性,因为系统回收时候,会根据importance的重要来杀进程的。具体可以去看文档。
IMPORTANCE_BACKGROUND = 400
public static final int IMPORTANCE_EMPTY = 500
public static final int IMPORTANCE_FOREGROUND = 100
public static final int IMPORTANCE_SERVICE = 300
public static final int IMPORTANCE_VISIBLE = 200


另外一种方法则可行:

[java] view plaincopy
  1. /** 
  2.  * 判断当前应用程序是否处于后台,通过getRunningTasks的方式 
  3.  * @return true 在后台; false 在前台 
  4.  */  
  5. public  boolean isApplicationBroughtToBackgroundByTask() {  
  6.     List<RunningTaskInfo> tasks = activityManager.getRunningTasks(1);  
  7.     if (!tasks.isEmpty()) {  
  8.         ComponentName topActivity = tasks.get(0).topActivity;  
  9.         if (!topActivity.getPackageName().equals(getPackageName())) {  
  10.             return true;  
  11.         }  
  12.     }  
  13.     return false;  
  14. }  


由于第一种方法在大部分情况下可行,所以继续沿用,并用第二种方法做保证。

全部代码,仅供参考:

[java] view plaincopy
  1. public class BaseActivity extends Activity {  
  2.     public static boolean notifyShowing = false;  
  3.     public static boolean isSpecialSystem=false;  
  4.     public void onCreate(Bundle bundle) {  
  5.         super.onCreate(bundle);  
  6.         MyRestoreInstanceState(bundle);  
  7.         sAllActivity.add(this);     
  8.         activityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);    
  9.         keyguardManager = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);  
  10.     }       
  11.   
  12.     protected void onStart() {  
  13.         super.onStart();  
  14.         if(notifyShowing){  
  15.             stopService(new Intent(this, LocalService.class));  
  16.             notifyShowing = false;  
  17.         }  
  18.     }  
  19.       
  20.     protected void onStop() {  
  21.         super.onStop();  
  22.         if(!isAppOnForeground()){  
  23.             notifyShowing = true;  
  24.             startService(new Intent(this, LocalService.class));  
  25.         }  
  26.     }  
  27.       
  28.     ActivityManager activityManager;  
  29.     KeyguardManager keyguardManager;  
  30.     /** 
  31.      * 判断程序是否在前台 
  32.      * @return true 在前台; false 在后台 
  33.      */  
  34.     private boolean isAppOnForeground() {     
  35.         if(!isSpecialSystem){  
  36.             boolean isspecial=true;  
  37.             String packageName = this.getPackageName();  
  38.             List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();     
  39.             if (appProcesses == null)   
  40.                 return false;     
  41.             for (RunningAppProcessInfo appProcess : appProcesses) {     
  42.                 if (appProcess.processName.equals(packageName)) {  
  43.                     if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND||appProcess.importance == RunningAppProcessInfo.IMPORTANCE_VISIBLE) {     
  44.                         return true;     
  45.                     }  
  46.                     if (keyguardManager.inKeyguardRestrictedInputMode()) return true;  
  47.                 }    
  48.                 if(isspecial){  
  49.                     if(appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND){  
  50.                         isspecial=false;  
  51.                     }  
  52.                 }  
  53.             }  
  54.             if(isspecial){  
  55.                 isSpecialSystem=true;  
  56.                 return !isApplicationBroughtToBackgroundByTask();  
  57.             }  
  58.             return false;     
  59.         }else{  
  60.             return !isApplicationBroughtToBackgroundByTask();  
  61.         }  
  62.     }     
  63.       
  64.     /** 
  65.      * 判断当前应用程序是否处于后台,通过getRunningTasks的方式 
  66.      * @return true 在后台; false 在前台 
  67.      */  
  68.     public  boolean isApplicationBroughtToBackgroundByTask() {  
  69.         List<RunningTaskInfo> tasks = activityManager.getRunningTasks(1);  
  70.         if (!tasks.isEmpty()) {  
  71.             ComponentName topActivity = tasks.get(0).topActivity;  
  72.             if (!topActivity.getPackageName().equals(getPackageName())) {  
  73.                 return true;  
  74.             }  
  75.         }  
  76.         return false;  
  77.     }  
  78.       
  79. }  

文章2:

http://blog.csdn.net/way_ping_li/article/details/17253943

在Android开发中,我们经常想知道是否自己的服务处于后台运行中,因为在后台运行的服务器优先级会降低,也就极有可能会被系统给回收掉,有什么好办法呢?Google推荐我们将服务运行到前台,如何知道服务是否处于后台运行呢?可以通过获取堆栈信息中栈顶的Activity是否为本应用即可。

1。下面是关健部分代码:

(记得加上权限:<uses-permission android:name="android.permission.GET_TASKS"/>)

mPackageName为本应用包名,mActivityManager为Activity管理对象

mActivityManager = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));

mPackageName = getPackageName();

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public boolean isAppOnForeground() {  
  2.     List<RunningTaskInfo> tasksInfo = mActivityManager.getRunningTasks(1);  
  3.     if (tasksInfo.size() > 0) {  
  4.         L.i("top Activity = "  
  5.                 + tasksInfo.get(0).topActivity.getPackageName());  
  6.         // 应用程序位于堆栈的顶层  
  7.         if (mPackageName.equals(tasksInfo.get(0).topActivity  
  8.                 .getPackageName())) {  
  9.             return true;  
  10.         }  
  11.     }  
  12.     return false;  
  13. }  

2。下面又会有一个新问题,我们什么时候调用这个函数呢?有两个办法,一个是主动,一个是被动,

①.主动办法:在服务中开启一个线程,每隔一段时间调用一下这个函数即可。

②.被动办法:自定义一个BaseActivity继承Activity,然后在onPause函数中回调通知一下服务中的此函数,然后应用中的每个Activity都继承BaseActivity,即可知道栈顶中是否还有本应用的Activity。


3.当我们知道栈顶中的Activity不是本应用的了,我们的服务也就相应的降低了优先级,也就说系统需要内存的时候,首先就会回收此服务消耗的内存。此时,我们只需将服务设置为前台运行即可:

①.设置为前台:第一个参数是通知ID,第二个参数是Notification对象

startForeground(SERVICE_NOTIFICATION, n);

②.停止前台服务可调用:true代表清除通知栏

stopForeground(true);

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public void updateServiceNotification(String message) {  
  2.         if (!PreferenceUtils.getPrefBoolean(this,  
  3.                 PreferenceConstants.FOREGROUND, true))  
  4.             return;  
  5.         String title = PreferenceUtils.getPrefString(this,  
  6.                 PreferenceConstants.ACCOUNT, "");  
  7.         Notification n = new Notification(R.drawable.login_default_avatar,  
  8.                 title, System.currentTimeMillis());  
  9.         n.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;  
  10.   
  11.         Intent notificationIntent = new Intent(this, MainActivity.class);  
  12.         notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
  13.         n.contentIntent = PendingIntent.getActivity(this0,  
  14.                 notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);  
  15.   
  16.         n.setLatestEventInfo(this, title, message, n.contentIntent);  
  17.         startForeground(SERVICE_NOTIFICATION, n);  
  18.     }  
  19.   
  20.     // 判断程序是否在后台运行的任务,其实个人觉得这个办法并不太好,  
  21.     Runnable monitorStatus = new Runnable() {  
  22.         public void run() {  
  23.             try {  
  24.                 L.i("monitorStatus is running... " + mPackageName);  
  25.                 mMainHandler.removeCallbacks(monitorStatus);  
  26.                 // 如果在后台运行并且连接上了  
  27.                 if (!isAppOnForeground()) {  
  28.                     L.i("app run in background...");  
  29.                     // if (isAuthenticated())//不判断是否连接上了。  
  30.                     updateServiceNotification(getString(R.string.run_bg_ticker));  
  31.                     return;// 服务已在前台运行,可以停止重复执行此任务  
  32.                 } else {  
  33.                     stopForeground(true);  
  34.                 }  
  35.                 mMainHandler.postDelayed(monitorStatus, 1000L);  
  36.             } catch (Exception e) {  
  37.                 e.printStackTrace();  
  38.                 L.i("monitorStatus:"+e.getMessage());  
  39.             }  
  40.         }  
  41.     };  


OK,以上仅是本人的一点心得体会,可能有不正确的地方,请大家甄别使用,谢谢!


http://blog.csdn.net/way_ping_li/article/details/17253943


文章3:

  1. 在Activity中的onStop方法中去判断当前的应用程序是否在后台运行,同时用一个成员变量去记录该Activity是否为后台,在onResume方法中去判断记录程序后台的变量是否为true,如为true就说明现在是程序从后台切换到前台了,这时候就要去刷新数据了

    /**
     * 用于记录当前应用程序是否在后台运行,这样只作用于一个Activity,如果想让所有的
     * Activity都知道程序从后台到前台了,这时候要弄一个基类BaseActivity了,在
     * BaseActivity中去执行这些代码,让其他的Activity都继承该BaseActivity。并且要将
     * isApplicationBroughtToBackground变成static的。
     * 然后在onResume方法中不要执行isApplicationBroughtToBackground = false;这样其他
     * Activity在onResume方法中判断时就知道应用是从后台切换到前台的了,不用担心这样会导
     * 致isApplicationBroughtToBackground无法恢复为false,因为在onStop方法中,我们
     * 判断了如果现在程序不是后台,就将isApplicationBroughtToBackground 变为false了
     */
    private boolean isApplicationBroughtToBackground;
    
    @Override
    protected void onStop() {
        super.onStop();
        if(isApplicationBroughtToBackground(this)) {
            //程序后台了
            LogUtil.i(TAG, "后台了...");
            isApplicationBroughtToBackground = true;
        }else {
            LogUtil.i(TAG, "木有后台");
            isApplicationBroughtToBackground = false;
        }
    
    }
    
    protected void onResume() {
        super.onResume();
        if(isApplicationBroughtToBackground) {
            //从后台切换到前台了
            LogUtil.i(TAG, "从后台切换到前台了,刷新数据");
            loadFocusInfoData();
        }
        isApplicationBroughtToBackground = false;
    };


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值