这里要考虑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); Listtasks = 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 ArrayListactivityList; public ActivityListUtil() { activityList = new ArrayList (); } 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(); } } } }}