zoukankan      html  css  js  c++  java
  • Android实现app长时间未操作时自动退出app

    这里要考虑3个问题,第一个是锁屏问题,第二个是app被切换至后台的问题,第三个是屏幕锁定和解除时app在后台时的问题

    一,监听屏幕解锁,锁定

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
           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.this1024, 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.this1024, 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    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类如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    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();
                    }
                }
            }
             
        }
    }

    http://my.oschina.net/ososchina/blog/374050?p=1

  • 相关阅读:
    Linux安装RocketMQ
    初识SpringMVC
    事物的锁机制和七种传播行为
    Spring事物
    JdbcTemplate模板
    注解
    AOP代理工厂方式实现增强
    面试题
    Spring框架静态代理和动态代理
    Bootstrap框架(基础篇)之按钮,网格,导航栏,下拉菜单
  • 原文地址:https://www.cnblogs.com/manmanlu/p/4826018.html
Copyright © 2011-2022 走看看