在我们实际的开发中。经常需要监听app锁屏或切后台,以便调起一个服务,使得App照常进行运行;或者是切换到前台,终止服务等等
下面我们提供两个方法来获取状态的变化:
方法1:通过ActivityLifecycleCallbacks
android 在从sdk14 开始为我们提供了一个新的api 用于检测app 中activity 的生命周期,正好我们app 的minSdkVersion 已经设置为 14 了。 所以现在我们可以使用ActivityLifecycleCallbacks来 监听app 是否运行在后台的行为了。
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 的生命周期,知道onStart() 一般表示一个Activity 处于前台,onStop() 一般表示Activity在后台不可见。
- 所以我们设置一个activityCount 变量, onActivityStarted 的时候activityCount++, onActivityStopped的时候activityCount–。
- 当onActivityStopped之后如果activityCount == 0 了。那么表示我们的app里面没有处于onStart的Activity 了,也就相当于 app 已经处于后台了。
想想为什么要在onStop中检测,而不是onPause?
这是由于A启动B时,生命周期的执行顺序如下:
A.onPause->B.onCreate->B.onStart->B.onResume->A.onStop
也就是说,在A的onPause方法中,B的生命周期还没有执行,进程没有进入前台。
代码如下:
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
/**
* Describe: 监听app锁屏或切后台
* Created by Gao Chunfa on 2020/3/19.
* Company: Hainan DaDi(Jinan) Network Technology Co. Ltd
*/
class ActivityLifecycleListener implements Application.ActivityLifecycleCallbacks {
private int activityCount = 0;
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
activityCount++;
getAppStatus();
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
activityCount--;
getAppStatus();
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
/**
* 根据activityCount,判断app状态
*/
public void getAppStatus() {
if (activityCount == 0) {
//App进入后台或者APP锁屏了
} else {
//App进入前台
}
}
}
方法2:监听系统的广播来实现
主要是监听Intent.ACTION_CLOSE_SYSTEM_DIALOGS 和 Intent.ACTION_SCREEN_OFF 这两个系统广播。
Receiver 的大概代码如下:
final String SYSTEM_DIALOG_REASON_KEY = "reason";
final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
final String SYSTEM_DIALOG_REASON_LOCK_KEY = "lock";
private class ScreenBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//按HOME键
if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (reason != null && (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY) || reason.equals(SYSTEM_DIALOG_REASON_LOCK_KEY))) {
//app 按HOME键
}
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
//app 锁屏
} else if (action.equals(Intent.ACTION_SCREEN_ON)) {
//app 亮屏
} else if (action.equals(Intent.ACTION_USER_PRESENT)) {
//app 解锁
}
}
}
大功告成~~