菜鸟入坑记——第一篇

关键字:AlarmManager

一、AlarmManager简介:

参考网址:https://www.jianshu.com/p/8a2ce9d02640
        参考网站:https://www.runoob.com/w3cnote/android-tutorial-alarmmanager.html

推荐此网址:https://www.jianshu.com/p/d69a90bc44c0

了解android低电耗模式:https://developer.android.google.cn/training/monitoring-device-state/doze-standby.html
        AlarmManager的作用:在特定的时刻为我们广播一个指定的Intent。
        即:自己设定一个时间,当系统时间到达此时间时,AlarmManager自动广播一个我们设定好的Intent,指向某个Activity或Service。
        注意:① AlarmManager主要用来在某个时刻运行你的代码,即使你的APP在那个特定的时间并没有运行。

二、获得AlarmManager实例对象:
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

三、方法:

setExact(int type, long startTime, PendingIntent pi); 一次性闹钟,执行时间精确,为精确闹钟

参数解释:此部分参考网站https://www.jianshu.com/p/8a2ce9d02640

四、程序设计:

(1)类型type

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

(2)开始时间startTime

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

 /**
      * String类型转换成date类型
      * strTime: 要转换的string类型的时间,
      * formatType: 要转换的格式yyyy-MM-dd HH:mm:ss
      * //yyyy年MM月dd日 HH时mm分ss秒,
      * strTime的时间格式必须要与formatType的时间格式相同
      */
     public static Date stringToDate(String strTime, String formatType){
         KLog.d("进入stringToDate");
         try {
             SimpleDateFormat formatter = new SimpleDateFormat(formatType);
             Date date = null;
             date = formatter.parse(strTime);
             return date;
         }catch (Exception e){
             return null;
         }
     }
     /**
      * String类型转换为long类型
      * .............................
      * strTime为要转换的String类型时间
      * formatType时间格式
      * formatType格式为yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
      * strTime的时间格式和formatType的时间格式必须相同
      */
     public static long stringToLong (String strTime,String formatType){
         KLog.d("进入stringToLong");
         try{
             //String类型转换为date类型
             Date date = stringToDate(strTime, formatType);
             Log.d(TAG,"调用stringToDate()获得的date:" + date);
             if (date == null) {
                 return 0;
             }else {
                 //date类型转成long类型
                 long Hour = date.getHours();
                 long Min = date.getMinutes();
                 long TimeLong = Hour*60*60*1000 + Min*60*1000;
                 Log.d(TAG,"stringToLong()获得的Hour:" + Hour + " h");
                 Log.d(TAG,"stringToLong()获得的Min:" + Min + " min");
                 Log.d(TAG,"stringToLong()获得的TimeLong:" + TimeLong + " ms");
                 return TimeLong;
             }
         }catch (Exception e){
             return 0;
         }
     }

Java Date、String、Long三种日期类型之间的相互转换

参考网址:http://www.blogjava.net/weishuangshuang/archive/2012/09/27/388712.html

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

         //计算时间间隔
         if (GET_UP_TIME >= SLEEP_TIME){
              IntervalTime = GET_UP_TIME - SLEEP_TIME;
         }else {
              IntervalTime = 24*60*60*1000 + GET_UP_TIME - SLEEP_TIME;
         }

(3)定义跳转Activity的操作:PendingIntent pi

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

 //设置当前的时间
 Calendar calendar = Calendar.getInstance();
 calendar.setTimeInMillis(System.currentTimeMillis());
 //根据用户选择的时间来设置Calender对象(即:睡觉时间)
 calendar.set(Calendar.HOUR_OF_DAY, (int)SLEEP_TIME_HOUR);
 calendar.set(Calendar.MINUTE, (int) SLEEP_TIME_MIN);
 calendar.set(Calendar.SECOND, 0);
 calendar.set(Calendar.MILLISECOND,0);
 //设置当前时区(若时区不对,闹钟将有偏差)
 TimeZone timeZone = TimeZone.getDefault();//获取系统时间时区
 KLog.d("当前设置的时区为: " + timeZone);
 calendar.setTimeZone(timeZone);
 KLog.d("睡觉时间:" + SLEEP_TIME + "ms, 起床时间:" + GET_UP_TIME + "ms.");
 KLog.d("夜间休息时长:IntervalTime = " + IntervalTime + "ms.");

定义intent操作:

1         //定义用于跳转到 LockScreenActivity.class 中的Intent对象intent
         Intent intent = new Intent(RobotClientMainActivity.this, LockScreenActivity.class);
         intent.putExtra("INTERVAL", IntervalTime);

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

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

PendingIntent.getActivity的使用:https://www.cnblogs.com/lyxin/p/5995681.html

 //初始化闹钟的执行操作pi
 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:

 //定义AlarmManager对象
     private AlarmManager alarmManager;
         //初始化alarmManager
         alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
         /**
          * 设置AlarmManager在Calendar对应的时间启动Activity
          * 当到达睡觉时间时跳转至LockScreenActivity执行锁屏操作
          */
         alarmManager.setExact(AlarmManager.RTC,calendar.getTimeInMillis(),pi);
         KLog.d("从calender中读取到的睡眠时间:" + calendar.getTime()
                 + "/n 毫秒:"+calendar.getTimeInMillis());

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

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

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

相关条件判断如下:

定义和初始化部分:

  //定义睡觉和起床时间单位ms
         long SLEEP_TIME,GET_UP_TIME;
         //睡觉和起床时间对应的小时数和分钟数
         long SLEEP_TIME_HOUR,SLEEP_TIME_MIN;
         long GET_UP_TIME_HOUR,GET_UP_TIME_MIN;
         //定义睡觉时间和起床时间之间的时间间隔
         long IntervalTime;
         //定义系统当前时间(单位ms)
         long CurrentTime_ms;
 //设置当前的时间
         Calendar calendar = Calendar.getInstance();
         calendar.setTimeInMillis(System.currentTimeMillis());
         KLog.d("111系统当前时间为:" + calendar.getTime());
         KLog.d("系统当前时间Hour:" + calendar.get(Calendar.HOUR_OF_DAY));
         KLog.d("系统当前时间Min:" + calendar.get(Calendar.MINUTE));
         KLog.d("系统当前时间Second:" + calendar.get(Calendar.SECOND));
         CurrentTime_ms = calendar.get(Calendar.HOUR_OF_DAY)*60*60*1000
                 +calendar.get(Calendar.MINUTE)*60*1000+calendar.get(Calendar.SECOND)*1000;

条件判断:

  /**
          * 计算夜间休息时长
          * 如果当前时间没到睡眠时间,则休息时长定为睡眠时间至起床时间
          * 若果当前时间在睡眠时间和起床时间之间,则休息时长定为当前时间至起床时间
          */
         if (GET_UP_TIME >= SLEEP_TIME) {
             if ((CurrentTime_ms >= SLEEP_TIME) && (CurrentTime_ms <= GET_UP_TIME)) {
                 IntervalTime = GET_UP_TIME - CurrentTime_ms;

             }else {
                 IntervalTime = GET_UP_TIME - SLEEP_TIME;
             }
         }else {
             if ((CurrentTime_ms <= SLEEP_TIME) && (CurrentTime_ms >= GET_UP_TIME)) {
                 IntervalTime = 24*60*60*1000 + GET_UP_TIME - SLEEP_TIME;
             }else {
                 if(CurrentTime_ms <= GET_UP_TIME) {
                     IntervalTime = GET_UP_TIME - CurrentTime_ms;
                 }else {
                     IntervalTime = 24*60*60*1000 + GET_UP_TIME - CurrentTime_ms;
                 }
             }
         }
         KLog.d("夜间休息时长:IntervalTime = " + IntervalTime + "ms.");
 /**
          * 设置AlarmManager在Calendar对应的时间启动Activity
          * 当到达睡觉时间时跳转至LockScreenActivity执行锁屏操作
          * 若系统当前时间已经不属于夜间休息时间,加入判断使程序不再调用alarmManager
          */
         if (GET_UP_TIME >= SLEEP_TIME) {
             if (CurrentTime_ms < GET_UP_TIME) {
                 KLog.d("当前时间 CurrentTime_ms = " + CurrentTime_ms + "ms");
                 KLog.d("起床时间 GET_UP_TIME = " + GET_UP_TIME + "ms");
                 alarmManager.setExact(AlarmManager.RTC,calendar.getTimeInMillis(),pi);
                 KLog.d("从calender中读取到的睡眠时间:" + calendar.getTime()
                         + "/n 毫秒:"+calendar.getTimeInMillis());
             }
         }else {
             KLog.d("当前时间 CurrentTime_ms = " + CurrentTime_ms + "ms");
             KLog.d("起床时间 GET_UP_TIME = " + GET_UP_TIME + "ms");
             alarmManager.setExact(AlarmManager.RTC,calendar.getTimeInMillis(),pi);
             KLog.d("从calender中读取到的睡眠时间:" + calendar.getTime()
                     + "/n 毫秒:"+calendar.getTimeInMillis());
         }

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

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

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

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

由于功能实现写于主页之中,只会初始化一次,所以在功能变更之后,必须关机重启才可生效。

不过我们可以在onResume方法中再次添加相关的功能实现,则不用重启亦可使功能生效。

Android定时锁屏功能实现(AlarmManager定时部分)的更多相关文章

  1. Android一键锁屏源码

    APK下载 源程序下载 锁屏流程如下(参考于Android一键锁屏开发全过程[源码][附图]) 源码参考于一键锁屏 源码 一共有2个Java文件: package com.example.onekey ...

  2. Android一键锁屏APP

    题记: 这个app完全是拾人牙慧,作为练手用的,其实没有什么原创的东西.当然,博客还是我自己写的,记录下来,对自己也算是一种成长吧. 转载请注明原文地址: http://www.cnblogs.com ...

  3. iOS开发——使用技术OC篇&简单九宫格锁屏功能的实现与封装

    简单九宫格锁屏功能的实现与封装 首先来看看最后的实现界面. 在这开始看下面的内容之前希望你能先大概思考活着回顾一下如果 你会怎么做,只要知道大概的思路就可以. 由于iphone5指纹解锁的实现是的这个 ...

  4. Android忘记锁屏密码如何进入手机?

    Android忘记锁屏密码如何进入手机?     1.关闭手机 2.进入recovery模式(即恢复模式,记住不是挖煤模式.进入恢复模式不同手机有不同方法,三星的话安主页键,关机键和音量+(或-键), ...

  5. Android逆向之旅---Android中锁屏密码算法解析以及破解方案

    一.前言 最近玩王者荣耀,下载了一个辅助样本,结果被锁机了,当然破解它很简单,这个后面会详细分析这个样本,但是因为这个样本引发出的欲望就是解析Android中锁屏密码算法,然后用一种高效的方式制作锁机 ...

  6. CentOS系统里如何正确取消或者延长屏幕保护自动锁屏功能(图文详解)

    不多说,直接上干货! 对于我这里想说的是,分别从CentOS6.X  和  CentOS7.X来谈及. 1. 问题:默认启动屏幕保护 问题描述: CentOS系统在用户闲置一段时间(默认为5分钟)后, ...

  7. 【Centos】Centos7.5取消自动锁屏功能

    目录 00. 目录 01. 问题描述 02. 问题分析 03. 解决办法 04. 附录 00. 目录 @ 参考博客:[Centos]Centos7.5取消自动锁屏功能 01. 问题描述 Centos7 ...

  8. 定时锁屏程序,Python祝你原理猝死!

    高以翔事件 11月27日在<追我吧>第九期节目的录制过程中,当期参与嘉宾高以翔奔跑时突然减速倒地,节目现场医护人员第一时间展开救治,并紧急将其送往医院.经过两个多小时的全力抢救,医院最终宣 ...

  9. Android开发之实现锁屏功能

    锁屏须要引入设备超级管理员.在文档Android开发文档的Administration中有具体的说明. Android设备管理系统功能和控制訪问. 主要有一下几个步骤: 1  创建广播接收者,实现De ...

随机推荐

  1. css常用知识与用法

    1 类选择器就是再 某一个标签后面加上class  =“”     然后再到前面去定义这个class   一定要记住前面加. 2 id选择器和类选择器是差不多的   不过id选择器前面不加.而加#   ...

  2. Android的简述2

    android提供了三种菜单类型,分别为options menu,context menu,sub menu. options menu就是通过按home键来显示,context menu需要在vie ...

  3. centos7更新yum库为aliyun库

    1. 备份原来的yum源$sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak 2.设置ali ...

  4. vue教程二 vue组件(2)

    每个组件都可以有自己的data.methods.computed和您之前看到的所有内容—就像Vue实例本身一样. 您可能已经注意到了组件和Vue实例之间的一个细微差别:Vue实例上的数据属性是一个对象 ...

  5. Git 从master拉取代码创建新分支

    从master拉取新分支并push到远端 开发过程中经常用到从master分支copy一个开发分支: 1.切换到被copy的分支(master),并且从远端拉取最新版本 $git checkout m ...

  6. 初识代理——Proxy

    无处不在的模式——Proxy 最近在看<设计模式之禅>,看到代理模式这一章的时候,发现自己在写spring项目的时候其实很多时候都用到了代理,无论是依赖注入.AOP还是其他,可以说是无处不 ...

  7. 分享我的GD32F450的IAP过程

    最近一个项目使用GD32F450VI+ESP8266需要做远程升级,基本参考正点原子IAP的那一章节,但是在GD32F450上却遇到了问题,无法跳转,然后使用正点原子的开发板stm32f429,以及s ...

  8. VS调试时修改代码

    最近碰到一个问题,就是vs在调试模式下无法修改代码之后再继续,这种严重影响工作效率的问题怎么能忍,所以决心把这个坑填满.网上搜了大堆有头无尾有尾无头的答案,我一个一个试了几乎都没啥用.最后通过不断的测 ...

  9. 如何实现css渐变圆角边框

    最近设计师的风格发生突变,一句话概括就是,能用渐变的地方绝对不用纯色.这不,就整出了一个渐变圆角边框.这渐变好做,圆角好做,渐变圆角也没问题,可是在加个边框还是有点坑的.没办法,看看怎么实现吧 bor ...

  10. java高并发系列 - 第25天:掌握JUC中的阻塞队列

    这是java高并发系列第25篇文章. 环境:jdk1.8. 本文内容 掌握Queue.BlockingQueue接口中常用的方法 介绍6中阻塞队列,及相关场景示例 重点掌握4种常用的阻塞队列 Queu ...