- /**
- * 程序前后台判断
- * @return
- */
- private boolean isAppOnForeground() {
- ActivityManager activityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
- String packageName = this.getPackageName();
- List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
- if (appProcesses == null)
- return false;
- for (RunningAppProcessInfo appProcess : appProcesses) {
- if (appProcess.processName.equals(packageName)
- && appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
- return true;
- }
- }
- return false;
- }
经过测试,在一般情况下可行,在某些经过简洁版本的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
另外一种方法则可行:
- /**
- * 判断当前应用程序是否处于后台,通过getRunningTasks的方式
- * @return true 在后台; false 在前台
- */
- public boolean isApplicationBroughtToBackgroundByTask() {
- List<RunningTaskInfo> tasks = activityManager.getRunningTasks(1);
- if (!tasks.isEmpty()) {
- ComponentName topActivity = tasks.get(0).topActivity;
- if (!topActivity.getPackageName().equals(getPackageName())) {
- return true;
- }
- }
- return false;
- }
由于第一种方法在大部分情况下可行,所以继续沿用,并用第二种方法做保证。
全部代码,仅供参考:
- public class BaseActivity extends Activity {
- public static boolean notifyShowing = false;
- public static boolean isSpecialSystem=false;
- public void onCreate(Bundle bundle) {
- super.onCreate(bundle);
- MyRestoreInstanceState(bundle);
- sAllActivity.add(this);
- activityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
- keyguardManager = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);
- }
- protected void onStart() {
- super.onStart();
- if(notifyShowing){
- stopService(new Intent(this, LocalService.class));
- notifyShowing = false;
- }
- }
- protected void onStop() {
- super.onStop();
- if(!isAppOnForeground()){
- notifyShowing = true;
- startService(new Intent(this, LocalService.class));
- }
- }
- ActivityManager activityManager;
- KeyguardManager keyguardManager;
- /**
- * 判断程序是否在前台
- * @return true 在前台; false 在后台
- */
- private boolean isAppOnForeground() {
- if(!isSpecialSystem){
- boolean isspecial=true;
- String packageName = this.getPackageName();
- List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
- if (appProcesses == null)
- return false;
- for (RunningAppProcessInfo appProcess : appProcesses) {
- if (appProcess.processName.equals(packageName)) {
- if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND||appProcess.importance == RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
- return true;
- }
- if (keyguardManager.inKeyguardRestrictedInputMode()) return true;
- }
- if(isspecial){
- if(appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
- isspecial=false;
- }
- }
- }
- if(isspecial){
- isSpecialSystem=true;
- return !isApplicationBroughtToBackgroundByTask();
- }
- return false;
- }else{
- return !isApplicationBroughtToBackgroundByTask();
- }
- }
- /**
- * 判断当前应用程序是否处于后台,通过getRunningTasks的方式
- * @return true 在后台; false 在前台
- */
- public boolean isApplicationBroughtToBackgroundByTask() {
- List<RunningTaskInfo> tasks = activityManager.getRunningTasks(1);
- if (!tasks.isEmpty()) {
- ComponentName topActivity = tasks.get(0).topActivity;
- if (!topActivity.getPackageName().equals(getPackageName())) {
- return true;
- }
- }
- return false;
- }
- }
文章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();
- public boolean isAppOnForeground() {
- List<RunningTaskInfo> tasksInfo = mActivityManager.getRunningTasks(1);
- if (tasksInfo.size() > 0) {
- L.i("top Activity = "
- + tasksInfo.get(0).topActivity.getPackageName());
- // 应用程序位于堆栈的顶层
- if (mPackageName.equals(tasksInfo.get(0).topActivity
- .getPackageName())) {
- return true;
- }
- }
- return false;
- }
2。下面又会有一个新问题,我们什么时候调用这个函数呢?有两个办法,一个是主动,一个是被动,
①.主动办法:在服务中开启一个线程,每隔一段时间调用一下这个函数即可。
②.被动办法:自定义一个BaseActivity继承Activity,然后在onPause函数中回调通知一下服务中的此函数,然后应用中的每个Activity都继承BaseActivity,即可知道栈顶中是否还有本应用的Activity。
3.当我们知道栈顶中的Activity不是本应用的了,我们的服务也就相应的降低了优先级,也就说系统需要内存的时候,首先就会回收此服务消耗的内存。此时,我们只需将服务设置为前台运行即可:
①.设置为前台:第一个参数是通知ID,第二个参数是Notification对象
startForeground(SERVICE_NOTIFICATION, n);
②.停止前台服务可调用:true代表清除通知栏
stopForeground(true);
- public void updateServiceNotification(String message) {
- if (!PreferenceUtils.getPrefBoolean(this,
- PreferenceConstants.FOREGROUND, true))
- return;
- String title = PreferenceUtils.getPrefString(this,
- PreferenceConstants.ACCOUNT, "");
- Notification n = new Notification(R.drawable.login_default_avatar,
- title, System.currentTimeMillis());
- n.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
- Intent notificationIntent = new Intent(this, MainActivity.class);
- notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- n.contentIntent = PendingIntent.getActivity(this, 0,
- notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- n.setLatestEventInfo(this, title, message, n.contentIntent);
- startForeground(SERVICE_NOTIFICATION, n);
- }
- // 判断程序是否在后台运行的任务,其实个人觉得这个办法并不太好,
- Runnable monitorStatus = new Runnable() {
- public void run() {
- try {
- L.i("monitorStatus is running... " + mPackageName);
- mMainHandler.removeCallbacks(monitorStatus);
- // 如果在后台运行并且连接上了
- if (!isAppOnForeground()) {
- L.i("app run in background...");
- // if (isAuthenticated())//不判断是否连接上了。
- updateServiceNotification(getString(R.string.run_bg_ticker));
- return;// 服务已在前台运行,可以停止重复执行此任务
- } else {
- stopForeground(true);
- }
- mMainHandler.postDelayed(monitorStatus, 1000L);
- } catch (Exception e) {
- e.printStackTrace();
- L.i("monitorStatus:"+e.getMessage());
- }
- }
- };
OK,以上仅是本人的一点心得体会,可能有不正确的地方,请大家甄别使用,谢谢!
http://blog.csdn.net/way_ping_li/article/details/17253943
文章3:
-
在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; };