android 设置界面10秒无操作退休,关于Android系统无用户操作相关处理

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

最近开发产品遇到一个需求:当Android系统若干时间内无用户操作响应时启动多媒体轮播应用。

####思路1:监听输入事件并对其处理

接到需求想到的一个土办法就是在android系统input事件响应端对相关输入事件进行处理,可以追溯到android系统输入事件的framework层处理,相关代码目录在frameworks/base/core/java/android/view下,

我起初的处理在在ViewRootImpl.java,读者如果对Android输入系统不熟悉的话,最好可以去了解下,这里我就不进行拓展。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23final class extends InputEventReceiver{

public (InputChannel inputChannel, Looper looper){

super(inputChannel, looper);

}

public void onInputEvent(InputEvent event){

Log.d(TAG ,"onInputEvent:"+event.toString());

enqueueInputEvent(event, this, 0, true);

}

public void onBatchedInputEventPending(){

scheduleConsumeBatchedInput();

}

public void dispose(){

unscheduleConsumeBatchedInput();

super.dispose();

}

}

在WindowInputEventReceiver这个类里面会接收到输入系统输入的各种事件,包括用户的触摸,遥控 ,鼠标操作,当有输入时候,WindowInputEventReceiver的onInputEvent()就会响应,这时候就知道系统有用户在操作了,那么你可以在这个函数里对产生输入事件的时间进行统计和运算,用户多久操作多久没操作你都清楚啦,你可以在这里通过广播或者其他途径告诉上层应用去做响应的处理,到此可以完成需求了。

####思路2:利用Android系统原有的休眠机制

Android系统本身是有无操作若干时间后自动休眠的功能,一般在设置程序中的显示这项中找到休眠一项,这里就直接给出相关的代码,实际上这里只是设置了一个SCREEN_OFF_TIMEOUT关键字的数据库字段,相关代码在设置程序的DisplaySettings中。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19public boolean onPreferenceChange(Preference preference, Object objValue){

final String key = preference.getKey();

if (KEY_SCREEN_TIMEOUT.equals(key)) {

int value = Integer.parseInt((String) objValue);

try {

//设置

Settings.System.putInt(getContentResolver(), SCREEN_OFF_TIMEOUT, value);

updateTimeoutPreferenceDescription(value);

} catch (NumberFormatException e) {

Log.e(TAG, "could not persist screen timeout setting", e);

}

}

if (KEY_FONT_SIZE.equals(key)) {

writeFontSizePreference(objValue);

}

return true;

}

那么实际上的操作处理在哪里呢,经过一段搜索后(搜索SCREEN_OFF_TIMEOUT关键字),我们发现是在PowerManagerService中查找到相关的处理,因为休眠部分涉及到电源管理,读者对这部分有疑问,建议去读下关于PowerManagerService的相关分析,在这里介绍调用到PowerManagerService里关键的方法updateUserActivitySummaryLocked()。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/**

* Updates the value of mUserActivitySummary to summarize the user requested

* state of the system such as whether the screen should be bright or dim.

* Note that user activity is ignored when the system is asleep.

*

* This function must have no other side-effects.

*/

private long mLastUserActivityTimeRecord =0;

private void updateUserActivitySummaryLocked(long now, int dirty){

Slog.d(TAG, "updateUserActivitySummaryLocked:"+now

+"mLastUserActivityTime:"+mLastUserActivityTime

+"mLastWakeTime:"+mLastWakeTime);

// Update the status of the user activity timeout timer.

if ((dirty & (DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {

mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);

long nextTimeout = 0;

if (mWakefulness != WAKEFULNESS_ASLEEP) {

final int screenOffTimeout = getScreenOffTimeoutLocked();

final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);

mUserActivitySummary = 0;

if (mLastUserActivityTime >= mLastWakeTime) {

nextTimeout = mLastUserActivityTime

+ screenOffTimeout - screenDimDuration;

if (now < nextTimeout) {

mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;

} else {

nextTimeout = mLastUserActivityTime + screenOffTimeout;

if (now < nextTimeout) {

mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;

}

}

}

if (mUserActivitySummary == 0

&& mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {

nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;

if (now < nextTimeout

&& mDisplayPowerRequest.screenState

!= DisplayPowerRequest.SCREEN_STATE_OFF) {

mUserActivitySummary = mDisplayPowerRequest.screenState

== DisplayPowerRequest.SCREEN_STATE_BRIGHT ?

USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;

}

}

if (mUserActivitySummary != 0) {

Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);

msg.setAsynchronous(true);

mHandler.sendMessageAtTime(msg, nextTimeout);

}

} else {

mUserActivitySummary = 0;

}

if (DEBUG_SPEW) {

Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="

+ wakefulnessToString(mWakefulness)

+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)

+ ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));

}

}

}

读者可以仔细读下这个部分的注释,大概意思是通过这个办法统计更新用户请求的一些信息和状态,通过打印发现这个方法在若干毫秒被系统调用的(具体的回调过程我还没仔细研究);需要注意的是这里有声明该方法内不能有其他副作用的操作,言下之意不能过多的操作不然系统会崩溃重启。这里我吃过苦头了,反复发一个intent也会导致系统重启,各位看官如果要操作之记得慎重操作。

需要注意的变量now,mLastUserActivityTime,now是通过SystemClock.uptimeMillis()获取,表示当前时间,mLastUserActivityTime表示用户上一次操作的时间,now和mLastUserActivityTime的对比可以知道距离用户上一次多久没有操作了。通过大家可以研读其中逻辑打印体会下。只要搞定了这个地方,可以满足目前的需求,而且不用单独去输入系统去做处理,这里的需求推荐思路2去实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值