Android实现App会话超时退出设计
来源:互联网 发布:英雄联盟无法连接网络 编辑:程序博客网 时间:2024/05/16 09:08
这里要考虑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.
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
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();
}
}
}
}
}
0 0
- Android实现App会话超时退出设计
- android自定义广播实现app完全退出
- android自定义广播实现app完全退出
- Android实现点击两次back退出APP
- Android中实现App的退出
- android自定义广播实现app完全退出
- Android开发,完全退出APP的实现
- Android中如何实现双击退出APP
- Android自定义广播实现app完全退出
- Android 实现双击返回键退出App
- Flex会话超时重新登录实现方法
- 代码实现退出app
- ios退出APP实现
- 会话超时
- android 退出APP
- android 完全退出App
- android 退出整个APP
- Android App 退出解决方案
- 【GoogleCodeJam2016D】【构造 找规律】Fractiles LG字符串K字符C次变为S个检测位置找金子
- 编译提示imgproc.hpp:50:33: 致命错误: opencv2/core/core.hpp:没有那个文件或目录解决办法
- 码农小汪-spring框架学习之6-spring基于注解的容器配置 @Qualifier @Autowired @Resouce @PostConstruct @PreDestroy
- hdu5294-网络流+最短路
- 用php写ftp爬虫
- Android实现App会话超时退出设计
- python的time模块
- 接口测试相关文档管理规范
- 用opencv保存视频为什么打不开?
- 13、MongoDB的分片,以及分布式的实现(分片,拆分的是集合,不是单条数据)
- springmvc 常用的绑定参数用法
- 仿微信的语音点击播放时的语音图标动画效果
- 查找内存泄漏的一个思路
- html元素