Android实现应用程序前台和后台之间转换的监听的两种

android中会使用很多监听本应用是处于前台还是后台的场景,接下来我介绍两种,不需要权限申请的。

第一种:使用ActivityManager,获取手机应用的所有进程,筛选出自己本应用的,根据importance来判断是否处于后台。

/**
	 * 判断当前程序是否在前台
	 * 
	 * @param context
	 * @return
	 */
	public static boolean isAppOnForeground(Context context) {
		ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
		if (appProcesses == null || appProcesses.size() <= 0) {
			return true;
		}
		for (RunningAppProcessInfo appProcess : appProcesses) {
			if (appProcess == null) {
				PLog.w("getProcess == null");
				return true;
			} else if (appProcess.processName.equals(context.getPackageName())) {
				PLog.i("isAppOnForeground importance = " + appProcess.importance);
				return appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND || appProcess.importance == RunningAppProcessInfo.IMPORTANCE_VISIBLE;
			}
		}
		return false;
	}

第二种:由前面那种也能看出来,有很多地方要进行异常处理,这样在某些情况下,获取到的前后台应用并不准确,所以我推荐第二种方法。本方法使用的是ActivityLifecycleCallbacks,可以看到这个接口中的方法,如下:

public interface ActivityLifecycleCallbacks {
        void onActivityCreated(Activity activity, Bundle savedInstanceState);
        void onActivityStarted(Activity activity);
        void onActivityResumed(Activity activity);
        void onActivityPaused(Activity activity);
        void onActivityStopped(Activity activity);
        void onActivitySaveInstanceState(Activity activity, Bundle outState);
        void onActivityDestroyed(Activity activity);
    }

使用的是activity的声明周期。接下来先上代码:

package com.example.testandroidmethod.utils;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;

import com.example.testandroidmethod.PLog;

/**
 * 监听前台后台应用的方法
 * @author boshuai.li
 * @date 创建时间:2018-7-10 上午10:09:37
 * @describe
 */
public class ForegroundCallbacks implements Application.ActivityLifecycleCallbacks {
	public static final long CHECK_DELAY = 500;
	public static final String TAG = ForegroundCallbacks.class.getName();

	public interface Listener {
		public void onBecameForeground();

		public void onBecameBackground();
	}

	private static ForegroundCallbacks instance;
	/**
	 * 默认启动时在前台
	 */
	private boolean foreground = true, paused = false;
	private static Handler handler = null;
	private List<Listener> listeners = new CopyOnWriteArrayList<Listener>();
	private Runnable check;

	/**
	 * 可使用context强转Application
	 * @param application
	 * @return
	 */
	public static ForegroundCallbacks init(Application application) {
		if (instance == null) {
			instance = new ForegroundCallbacks();
			application.registerActivityLifecycleCallbacks(instance);
			HandlerThread handlerThread = new HandlerThread("thread_foregroundcallbacks");
			handlerThread.start();
			
			handler = new Handler(handlerThread.getLooper());
		}
		return instance;
	}
	
	public static void uninit(Application application) {
		if (instance != null) {
			application.unregisterActivityLifecycleCallbacks(instance);
			instance = null;
		}
	}

	public static ForegroundCallbacks get(Application application) {
		if (instance == null) {
			init(application);
		}
		return instance;
	}

	public static ForegroundCallbacks get(Context ctx) {
		if (instance == null) {
			Context appCtx = ctx.getApplicationContext();
			if (appCtx instanceof Application) {
				init((Application) appCtx);
			}
			throw new IllegalStateException("Foreground is not initialised and " + "cannot obtain the Application object");
		}
		return instance;
	}

	public static ForegroundCallbacks get() {
		if (instance == null) {
			throw new IllegalStateException("Foreground is not initialised - invoke " + "at least once with parameterised init/get");
		}
		return instance;
	}

	public boolean isForeground() {
		return foreground;
	}

	public boolean isBackground() {
		return !foreground;
	}

	public void addListener(Listener listener) {
		listeners.add(listener);
	}

	public void removeListener(Listener listener) {
		listeners.remove(listener);
	}

	@Override
	public void onActivityResumed(Activity activity) {
		PLog.i("onActivityResumed activity =" + activity);
		paused = false;
		boolean wasBackground = !foreground;
		foreground = true;
		if (check != null)
			handler.removeCallbacks(check);
		if (wasBackground) {
			PLog.e("went foreground");
			handler.post(new Runnable() {
				
				@Override
				public void run() {
					for (Listener l : listeners) {
						try {
							l.onBecameForeground();
						} catch (Exception exc) {
							PLog.e("Listener threw exception!", exc);
						}
					}
					
				}
			});
		} else {
			PLog.e("still foreground");
		}
	}

	@Override
	public void onActivityPaused(Activity activity) {
		PLog.i("onActivityPaused activity =" + activity);
		paused = true;
		if (check != null)
			handler.removeCallbacks(check);
		handler.postDelayed(check = new Runnable() {
			@Override
			public void run() {
				if (foreground && paused) {
					foreground = false;
					PLog.e("went background");
					for (Listener l : listeners) {
						try {
							l.onBecameBackground();
						} catch (Exception exc) {
							PLog.e("Listener threw exception!", exc);
						}
					}
				} else {
					PLog.e("still foreground");
				}
			}
		}, CHECK_DELAY);
	}

	@Override
	public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
		PLog.i("onActivityCreated activity =" + activity);
	}

	@Override
	public void onActivityStarted(Activity activity) {
		PLog.i("onActivityStarted activity =" + activity);
	}

	@Override
	public void onActivityStopped(Activity activity) {
		PLog.i("onActivityStopped activity =" + activity);
	}

	@Override
	public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
		PLog.i("onActivitySaveInstanceState activity =" + activity);
	}

	@Override
	public void onActivityDestroyed(Activity activity) {
		PLog.i("onActivityDestroyed activity =" + activity);
	}
}

测试方法:

private void testIsForegroundApp() {
	final ForegroundCallbacks foregroundCallbacks = ForegroundCallbacks.get(this.getApplication());
	Timer timer = new Timer();
	TimerTask task = new TimerTask() {

		@Override
		public void run() {
			boolean isForeground = foregroundCallbacks.isForeground();
			if (isForeground) {
				PLog.i("当前是在前台");
			} else {
				PLog.i("当前是在后台");
			}

		}
	};
	timer.schedule(task, 0, 1000L);
}

由于本方法使用的是activity的生命周期,所以判断比较准确,但是如果要判断当前顶端正在使用的是那个应用,那还是别想了,现在很多机型都做了限制,在一些机子上还是可以用一些方法获取的,以上就是全部。

发布了15 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/HeartCircle/article/details/98060106