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

    }
}
posted @ 2017-11-23 16:10  dub  阅读(5342)  评论(0编辑  收藏  举报