1 Home key/ Recent Apps
如果只是监听Home Key / Recent Apps,可以通过注册广播接收器来实现。因为在当前操作下app进入后台是由系统发出的关闭窗口的动作
→ 广播接收器
public class CustomReceiver extends BroadcastReceiver {
private static final String LOG_TAG = "HomeReceiver";
private static final String SYSTEM_DIALOG_REASON_KEY = "reason";
//action内的某些reason
private static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
private static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {//Action
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (SYSTEM_DIALOG_REASON_HOME_KEY.equals(reason)) {
//home 键
} else if (SYSTEM_DIALOG_REASON_RECENT_APPS.equals(reason)) {
//最近app 列表
} else {
}
}
}
}
// 锁屏,监听Intent.ACTION_SCREEN_OFF这个Action
→ 动态 注册/注销 广播接收器
private static CustomReceiver customReceiver = null;
private static void registerCustomReceiver(Context context) {
customReceiver = new CustomReceiver();
final IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.registerReceiver(customReceiver, filter);
}
private static void unregisterCustomReceiver(Context context) {
if (customReceiver != null) {
context.unregisterReceiver(customReceiver);
}
}
@Override
protected void onResume() {
super.onResume();
registerCustomReceiver(this);
}
@Override
protected void onPause() {
unregisterCustomReceiver(this);
super.onPause();
}
2 所有退入后台方式的监听
通过拦截系统关闭窗口的动作,具有局限性,不涵盖所有场景。比如从状态栏的通知跳转到另外的app中,这个时候是打开Activity的方式开启了新的app,那么当前app的Activity只有生命周期的变化,仅是这样无法判断当前app是否切入后台。所以,需要从整个应用层面去考虑,这里就用到了application
android系统会为每个程序运行时创建一个Application类的对象且仅创建一个【全局的单例的】,所以Application可以说是单例 (singleton)模式的一个类【自定义时需要注意构造器必须是public】。它的生命周期就等于这个程序的生命周期。通过自定义Application,可以完成初始化全局的数据、数据共享、对所有Activity的管理
在Application
类中存在一个registerActivityLifecycleCallbacks
方法,该方法接受一个ActivityLifecycleCallbacks
接口,该接口内的方法一一对应Activity的生命周期,并在Activity生命周期发生变化时回调对应的方法。
→ 适配ActivityLifecycleCallbacks接口
实现其所有方法,在使用的时候可以仅关心自己需要的回调
public class SimpleActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}
→ 创建一个工具类,在工具类中调用Application.registerActivityLifecycleCallbacks
public class AppStateTracker {
public static final int STATE_FOREGROUND = 0;
public static final int STATE_BACKGROUND = 1;
private static int currentState;
private boolean appInteractive = false; //提供给局部模块 判断app切后台
public static int getCurrentState() {
return currentState;
}
public static boolean isAppInteractive() {
return appInteractive;
}
/**
*
public interface AppStateChangeListener {
void appTurnIntoForeground();
void appTurnIntoBackGround();
}
*/
public static void track(Application application)
//, final AppStateChangeListener appStateChangeListener) 当需要Application需要回调时使用
{
application.registerActivityLifecycleCallbacks(new SimpleActivityLifecycleCallbacks(){
private int resumeActivityCount = 0;
@Override
public void onActivityStarted(Activity activity) {
if (resumeActivityCount==0){
currentState = STATE_FOREGROUND;
// appStateChangeListener.appTurnIntoForeground();
}
resumeActivityCount++;
}
@Override
public void onActivityResumed(Activity activity) {
appInteractive = true;
}
@Override
public void onActivityPaused(Activity activity) {
appInteractive = false;
}
@Override
public void onActivityStopped(Activity activity) {
resumeActivityCount--;
if (resumeActivityCount==0){
currentState = STATE_BACKGROUND;
// appStateChangeListener.appTurnIntoBackGround();
// todo: 做一些全局的操作
}
}
});
}
// 适配ActivityLifecycleCallback
private static class SimpleActivityLifecycleCallbacks implements Application
.ActivityLifecycleCallbacks{
//...
}
当需要从全局的角度需要做一些app切后台的操作时, 写在onStopped中,或者写在Application的appTurnIntoBackGround()回调。如果只是某个局部模块需要判断app切后台,直接使用变量currentState和appInteracttive都可以判断。appInteractive这个变量,当app最小化,Activity生命周期最终执行onActivityPaused ()【appInteractive为false】, 而如果是点击结果/返回,始终会有新的Activity显示,那么最终执行onActivityResumed()【appInteractive为true】