监听app切入后台

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】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值