Android实现app长时间未操作时自动退出app
这里要考虑3个问题,第一个是锁屏问题,第二个是app被切换至后台的问题,第三个是屏幕锁定和解除时app在后台时的问题
一,监听屏幕解锁,锁定
public class ScreenObserver {
private static String TAG = "ScreenObserver";
private Context mContext;
private ScreenBroadcastReceiver mScreenReceiver;
private ScreenStateListener mScreenStateListener;
private static Method mReflectScreenState;
public ScreenObserver(Context context) {
mContext = context;
mScreenReceiver = new ScreenBroadcastReceiver();
try {
mReflectScreenState = PowerManager.class.getMethod("isScreenOn",
new Class[] {});
} catch (NoSuchMethodException nsme) {
Log.d(TAG, "API < 7," + nsme);
}
}
/**
* screen状态广播接收者
*
* @author xishaomin
*
*/
private class ScreenBroadcastReceiver extends BroadcastReceiver {
private String action = null;
@Override
public void onReceive(Context context, Intent intent) {
action = intent.getAction();
if (Intent.ACTION_SCREEN_ON.equals(action)) {
mScreenStateListener.onScreenOn();
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
mScreenStateListener.onScreenOff();
}else if(Intent.ACTION_USER_PRESENT.equals(action)){
LogUtils.d("---->屏幕解锁完成");
}
}
}
/**
* 请求screen状态更新
*
* @param listener
*/
public void requestScreenStateUpdate(ScreenStateListener listener) {
mScreenStateListener = listener;
startScreenBroadcastReceiver();
firstGetScreenState();
}
/**
* 第一次请求screen状态
*/
private void firstGetScreenState() {
PowerManager manager = (PowerManager) mContext
.getSystemService(Activity.POWER_SERVICE);
if (isScreenOn(manager)) {
if (mScreenStateListener != null) {
mScreenStateListener.onScreenOn();
}
} else {
if (mScreenStateListener != null) {
mScreenStateListener.onScreenOff();
}
}
}
/**
* 停止screen状态更新
*/
public void stopScreenStateUpdate() {
mContext.unregisterReceiver(mScreenReceiver);
}
/**
* 启动screen状态广播接收器
*/
private void startScreenBroadcastReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
//当用户解锁屏幕时
filter.addAction(Intent.ACTION_USER_PRESENT);
mContext.registerReceiver(mScreenReceiver, filter);
}
/**
* screen是否打开状态
*
* @param pm
* @return
*/
private static boolean isScreenOn(PowerManager pm) {
boolean screenState;
try {
screenState = (Boolean) mReflectScreenState.invoke(pm);
} catch (Exception e) {
screenState = false;
}
return screenState;
}
public interface ScreenStateListener {
public void onScreenOn();
public void onScreenOff();
}
/**
* 判断屏幕是否已被锁定
* @param c
* @return
*/
public final static boolean isScreenLocked(Context c)
{
android.app.KeyguardManager mKeyguardManager = (KeyguardManager) c
.getSystemService(Context.KEYGUARD_SERVICE);
return mKeyguardManager.inKeyguardRestrictedInputMode();
}
/**
* 判断当前应用是否是本应用
* @param context
* @return
*/
public static boolean isApplicationBroughtToBackground(final Context context) {
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
return true;
}
}
return false;
}
}
然后在app的BaseActivity中实现ScreenObserver
private ScreenObservermScreenObserver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mScreenObserver = new ScreenObserver(this);
mScreenObserver.requestScreenStateUpdate(new ScreenStateListener() {
@Override
public void onScreenOn() {
if(!ScreenObserver.isApplicationBroughtToBackground(MainActivity.this))
{
cancelAlarmManager();
}
}
@Override
public void onScreenOff() {
if(!ScreenObserver.isApplicationBroughtToBackground(MainActivity.this))
{
cancelAlarmManager();
setAlarmManager();
}
}
});
}
///此处省略一大坨代码
/**
* 设置定时器管理器
*/
private void setAlarmManager()
{
long numTimeout = 300*1000;//5分钟
LogUtils.d("isTimeOutMode=yes,timeout="+numTimeout);
Intent alarmIntent = new Intent(MainActivity.this, TimeoutService.class);
alarmIntent.putExtra("action", "timeout"); //自定义参数
PendingIntent pi = PendingIntent.getService(MainActivity.this, 1024, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
long triggerAtTime = (System.currentTimeMillis()+numTimeout);
am.set(AlarmManager.RTC_WAKEUP, triggerAtTime, pi); //设定的一次性闹钟,这里决定是否使用绝对时间
LogUtils.d("----->设置定时器");
}
/**
* 取消定时管理器
*/
private void cancelAlarmManager()
{
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(MainActivity.this, TimeoutService.class);
PendingIntent pi = PendingIntent.getService(MainActivity.this, 1024, intent,PendingIntent.FLAG_UPDATE_CURRENT);
// 与上面的intent匹配(filterEquals(intent))的闹钟会被取消
alarmMgr.cancel(pi);
LogUtils.d("----->取消定时器");
}
@Override
protected void onResume() {
LogUtils.e("MainActivity-onResume");
super.onResume();
cancelAlarmManager();
activityIsActive = true;
LogUtils.d("activityIsActive="+activityIsActive);
}
@Override
protected void onStop() {
LogUtils.e("onStop");
super.onStop();
if (ScreenObserver.isApplicationBroughtToBackground(this))
{
cancelAlarmManager();
setAlarmManager();
}
}
然后在后台finishActivity
public class TimeoutService extends Service implements AppConstants {
@Override
public IBinder onBind(Intent arg0) {
return null;
}
boolean isrun = true;
@Override
public void onCreate() {
LogUtils.e("BindService-->onCreate()");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LogUtils.e("BindService-->onStartCommand()");
forceApplicationExit();
return super.onStartCommand(intent, flags, startId);
}
private void forceApplicationExit()
{
new Thread(new Runnable() {
@Override
public void run() {
ActivityListUtil.getInstence().cleanActivityList();
stopSelf();
}
}).start();
}
@Override
public void onDestroy() {
super.onDestroy();
isrun = false;
}
}
ActivityListUtil类如下
public class ActivityListUtil {
private static ActivityListUtil instence;
public ArrayList<Activity> activityList;
public ActivityListUtil() {
activityList = new ArrayList<Activity>();
}
public static ActivityListUtil getInstence()
{
if (instence == null) {
instence = new ActivityListUtil();
}
return instence;
}
public void addActivityToList(Activity activity) {
if(activity!=null)
{
activityList.add(activity);
}
}
public void removeActivityFromList(Activity activity)
{
if(activityList!=null && activityList.size()>0)
{
activityList.remove(activity);
}
}
public void cleanActivityList() {
if (activityList!=null && activityList.size() > 0) {
for (int i = 0; i < activityList.size(); i++) {
Activity activity = activityList.get(i);
if(activity!=null && !activity.isFinishing())
{
activity.finish();
}
}
}
}
}