定时锁屏 android,Android定时锁屏功能实现(AlarmManager定时部分)

菜鸟入坑记——第一篇

关键字:alarmmanager

一、alarmmanager简介:

参考网址:

参考网站:

推荐此网址:

了解android低电耗模式:

alarmmanager的作用:在特定的时刻为我们广播一个指定的intent。

即:自己设定一个时间,当系统时间到达此时间时,alarmmanager自动广播一个我们设定好的intent,指向某个activity或service。

注意:① alarmmanager主要用来在某个时刻运行你的代码,即使你的app在那个特定的时间并没有运行。

二、获得alarmmanager实例对象:

alarmmanager alarmmanager = (alarmmanager) getsystemservice(alarm_service);

三、方法:

setexact(int type, long starttime, pendingintent pi); 一次性闹钟,执行时间精确,为精确闹钟

参数解释:此部分参考网站

四、程序设计:

(1)类型type

此处选用闹钟类型为alarmmanager.rtc:闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间(当前系统时间),状态值为1。

(2)开始时间starttime

由于通过sp获得的时间为string类型,需先转换为long类型,且时间单位为ms

1 /**

2 * string类型转换成date类型

3 * strtime: 要转换的string类型的时间,

4 * formattype: 要转换的格式yyyy-mm-dd hh:mm:ss

5 * //yyyy年mm月dd日 hh时mm分ss秒,

6 * strtime的时间格式必须要与formattype的时间格式相同

7 */

8 public static date stringtodate(string strtime, string formattype){

9 klog.d("进入stringtodate");

10 try {

11 simpledateformat formatter = new simpledateformat(formattype);

12 date date = null;

13 date = formatter.parse(strtime);

14 return date;

15 }catch (exception e){

16 return null;

17 }

18 }

19 /**

20 * string类型转换为long类型

21 * .............................

22 * strtime为要转换的string类型时间

23 * formattype时间格式

24 * formattype格式为yyyy-mm-dd hh:mm:ss//yyyy年mm月dd日 hh时mm分ss秒

25 * strtime的时间格式和formattype的时间格式必须相同

26 */

27 public static long stringtolong (string strtime,string formattype){

28 klog.d("进入stringtolong");

29 try{

30 //string类型转换为date类型

31 date date = stringtodate(strtime, formattype);

32 log.d(tag,"调用stringtodate()获得的date:" + date);

33 if (date == null) {

34 return 0;

35 }else {

36 //date类型转成long类型

37 long hour = date.gethours();

38 long min = date.getminutes();

39 long timelong = hour*60*60*1000 + min*60*1000;

40 log.d(tag,"stringtolong()获得的hour:" + hour + " h");

41 log.d(tag,"stringtolong()获得的min:" + min + " min");

42 log.d(tag,"stringtolong()获得的timelong:" + timelong + " ms");

43 return timelong;

44 }

45 }catch (exception e){

46 return 0;

47 }

48 }

java date、string、long三种日期类型之间的相互转换

参考网址:

成功获得睡眠时间(sleep_time)和起床时间(get_up_time)(单位ms)之后,计算锁屏时间intervaltime(睡眠时间至起床时间):

1 //计算时间间隔

2 if (get_up_time >= sleep_time){

3 intervaltime = get_up_time - sleep_time;

4 }else {

5 intervaltime = 24*60*60*1000 + get_up_time - sleep_time;

6 }

(3)定义跳转activity的操作:pendingintent pi

我们的目的是利用alarmmanager的set()方法让闹钟在我们指定的时间点执行我们自定义的intent操作。这里时间点的设置非常重要,若时间设置的不精确(一般精确到秒即可,以下代码中精确至ms),将会导致闹钟执行intent有延迟。(sleep_time_hour和sleep_time_min分布是睡眠时间的小时数和分钟数)

1 //设置当前的时间

2 calendar calendar = calendar.getinstance();

3 calendar.settimeinmillis(system.currenttimemillis());

4 //根据用户选择的时间来设置calender对象(即:睡觉时间)

5 calendar.set(calendar.hour_of_day, (int)sleep_time_hour);

6 calendar.set(calendar.minute, (int) sleep_time_min);

7 calendar.set(calendar.second, 0);

8 calendar.set(calendar.millisecond,0);

9 //设置当前时区(若时区不对,闹钟将有偏差)

10 timezone timezone = timezone.getdefault();//获取系统时间时区

11 klog.d("当前设置的时区为: " + timezone);

12 calendar.settimezone(timezone);

13 klog.d("睡觉时间:" + sleep_time + "ms, 起床时间:" + get_up_time + "ms.");

14 klog.d("夜间休息时长:intervaltime = " + intervaltime + "ms.");

定义intent操作:

1 //定义用于跳转到 lockscreenactivity.class 中的intent对象intent

2 intent intent = new intent(robotclientmainactivity.this, lockscreenactivity.class);

3 intent.putextra("interval", intervaltime);

putextra("interval", intervaltime); "interval"为关键字,intervaltime为传入值(此处指睡眠时锁屏的时间ms)。带值跳转至lockscreenactivity.class中,lockscreenactivity执行相应的锁屏操作。

初始化闹钟的执行操作pi:

pendingintent.getactivity的使用:

1 //初始化闹钟的执行操作pi

2 pi = pendingintent.getactivity(robotclientmainactivity.this,0

,intent,pendingintent.flag_update_current);

方法:pendingintent.getactivity(context context, int requestcode, intent intent, int flags);

第一个参数是上下文context;

第二个参数是请求码,用于标识此pendingintent的对象,相当于关键字;

第三个参数是意图,用于跳转activity;

第四个参数代表了pendingintent的四种不同的状态,可用理解为状态标识符。四种状态如下:

①flag_cancel_current:

如果当前系统中已经存在一个相同的pendingintent对象,则已有的pendingintent将会取消,然后重新生成一个pendingintent对象。

②flag_no_create:

如果当前系统中不存在相同的pendingintent对象,系统将不会创建该pendingintent对象,而是直接返回null。

③flag_one_shot:

该pendingintent只作用一次。在该pendingintent对象通过send()方法触发过后,pendingintent将自动调用cancel()进行销毁,如果你再调用send()方法,系统将会返回一个sendintentexception。

④flag_update_current:

如果系统中有一个和你描述的pendingintent对等的pendingintent,那么系统将使用该pendingintent对象,但是会使用新的intent来更新之前pendingintent中的intent对象数据,例如更新intent中的extras。

(4)设置alarmmanager:

1 //定义alarmmanager对象

2 private alarmmanager alarmmanager;

1 //初始化alarmmanager

2 alarmmanager = (alarmmanager) getsystemservice(alarm_service);

1 /**

2 * 设置alarmmanager在calendar对应的时间启动activity

3 * 当到达睡觉时间时跳转至lockscreenactivity执行锁屏操作

4 */

5 alarmmanager.setexact(alarmmanager.rtc,calendar.gettimeinmillis(),pi);

6 klog.d("从calender中读取到的睡眠时间:" + calendar.gettime()

7 + "/n 毫秒:"+calendar.gettimeinmillis());

在此处,系统已经能够在指定的时间跳转至锁屏操作。但是实践中出现的问题是:只要系统时间已经超过指定时间,关机重启时会自动跳入锁屏操作——为什么???。。。:(  。。。求大神指导

********************************************************************************************************************************************************************************************************************************************************************************

虽然没有弄清alarmmanager.setexact的机制;但是利用其在实践中的表现(指过了锁屏时间重启后仍会锁屏),在关键时间点加入if/else的判断,成功实现了功能。

相关条件判断如下:

定义和初始化部分:

1 //定义睡觉和起床时间单位ms

2 long sleep_time,get_up_time;

3 //睡觉和起床时间对应的小时数和分钟数

4 long sleep_time_hour,sleep_time_min;

5 long get_up_time_hour,get_up_time_min;

6 //定义睡觉时间和起床时间之间的时间间隔

7 long intervaltime;

8 //定义系统当前时间(单位ms)

9 long currenttime_ms;

1 //设置当前的时间

2 calendar calendar = calendar.getinstance();

3 calendar.settimeinmillis(system.currenttimemillis());

4 klog.d("111系统当前时间为:" + calendar.gettime());

5 klog.d("系统当前时间hour:" + calendar.get(calendar.hour_of_day));

6 klog.d("系统当前时间min:" + calendar.get(calendar.minute));

7 klog.d("系统当前时间second:" + calendar.get(calendar.second));

8 currenttime_ms = calendar.get(calendar.hour_of_day)*60*60*1000

9 +calendar.get(calendar.minute)*60*1000+calendar.get(calendar.second)*1000;

条件判断:

1 /**

2 * 计算夜间休息时长

3 * 如果当前时间没到睡眠时间,则休息时长定为睡眠时间至起床时间

4 * 若果当前时间在睡眠时间和起床时间之间,则休息时长定为当前时间至起床时间

5 */

6 if (get_up_time >= sleep_time) {

7 if ((currenttime_ms >= sleep_time) && (currenttime_ms <= get_up_time)) {

8 intervaltime = get_up_time - currenttime_ms;

9

10 }else {

11 intervaltime = get_up_time - sleep_time;

12 }

13 }else {

14 if ((currenttime_ms <= sleep_time) && (currenttime_ms >= get_up_time)) {

15 intervaltime = 24*60*60*1000 + get_up_time - sleep_time;

16 }else {

17 if(currenttime_ms <= get_up_time) {

18 intervaltime = get_up_time - currenttime_ms;

19 }else {

20 intervaltime = 24*60*60*1000 + get_up_time - currenttime_ms;

21 }

22 }

23 }

24 klog.d("夜间休息时长:intervaltime = " + intervaltime + "ms.");

1 /**

2 * 设置alarmmanager在calendar对应的时间启动activity

3 * 当到达睡觉时间时跳转至lockscreenactivity执行锁屏操作

4 * 若系统当前时间已经不属于夜间休息时间,加入判断使程序不再调用alarmmanager

5 */

6 if (get_up_time >= sleep_time) {

7 if (currenttime_ms < get_up_time) {

8 klog.d("当前时间 currenttime_ms = " + currenttime_ms + "ms");

9 klog.d("起床时间 get_up_time = " + get_up_time + "ms");

10 alarmmanager.setexact(alarmmanager.rtc,calendar.gettimeinmillis(),pi);

11 klog.d("从calender中读取到的睡眠时间:" + calendar.gettime()

12 + "/n 毫秒:"+calendar.gettimeinmillis());

13 }

14 }else {

15 klog.d("当前时间 currenttime_ms = " + currenttime_ms + "ms");

16 klog.d("起床时间 get_up_time = " + get_up_time + "ms");

17 alarmmanager.setexact(alarmmanager.rtc,calendar.gettimeinmillis(),pi);

18 klog.d("从calender中读取到的睡眠时间:" + calendar.gettime()

19 + "/n 毫秒:"+calendar.gettimeinmillis());

20 }

实现功能:在指定时间范围内对app锁屏,在锁屏时间内,重启app仍可锁屏,不会因重启而终止整个锁屏活动。

小结:查阅了n多资料,终于实现了这一功能(*^▽^*),虽然还有许多不懂的地方,但是我会继续努力的。

最后,大神们给给意见撒。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值