Android 实现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();
				}
			}
		}
		
	}
}


转载于:https://my.oschina.net/ososchina/blog/374050

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值