zoukankan      html  css  js  c++  java
  • android service 在睡眠模式下失效,注册系统闹钟来实现在锁屏时候的提醒

      在做一个定时关闭服务的需求时候遇到service在手机休眠的时候在特定时间关闭应用失效的问题,若让屏幕亮着或者让service一直运行也比较耗电,因此设计到2个知识点:

          PowerManager 的 WakeLock 

       AlarmManager闹钟使用

    在注册系统提示服务即闹钟,到点后发送广播,然后在服务中注册广播接收器(service虽然休眠,但注册的广播接收器还是可以接受广播并执行相应的操作),接收到广播后就获取唤醒锁一段时间,让服务执行相应的操作。

    1、利用唤醒锁机制:PowerManagerWakeLock 

    关于该知识的介绍网上很多资料:http://blog.csdn.net/ryantang03/article/details/8628753/

    常用的一种方式如下:

    WakeLock wakeLock = null;  
        //获取电源锁,保持该服务在屏幕熄灭时仍然获取CPU时,保持运行  
        private void acquireWakeLock()  
        {  
            if (null == wakeLock)  
            {  
                PowerManager pm = (PowerManager)this.getSystemService(Context.POWER_SERVICE);  
                wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE, "PostLocationService");  
                if (null != wakeLock)  
                {  
                    wakeLock.acquire();  
                }  
            }  
        }  
          
        //释放设备电源锁  
        private void releaseWakeLock()  
        {  
            if (null != wakeLock)  
            {  
                wakeLock.release();  
                wakeLock = null;  
            }  
        }  
    

     主要注意3点:

    1、设置锁的计数类型

    mWakeLock.setReferenceCounted(false);

      在创建了PowerManager.WakeLock 后,有两种机制,第一种是不计数锁机制,另一种是计数锁机制。这可以通过setReferenceCounted( boolean value) 来指定,默认为计数机制。这两种机制的区别在于,前者无论acquire() 了多少次,只要通过一次release() 即可解锁。而后者正真解锁是在(--count == 0 )的时候,同样当(count == 0) 的时候才会去申请加锁,其他情况下isHeld 状态是不会改变的。所以PowerManager.WakeLock 的计数机制并不是正真意义上的对每次请求进行申请/释放每一把锁,它只是对同一把锁被申请/释放的次数进行了统计。(摘自:http://blog.csdn.net/zhandoushi1982/article/details/8513203)。

    2、锁初始化时关于cpu、键盘、屏幕的类型参数

    各种锁的类型对CPU 、屏幕、键盘的影响:

    PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的。

    SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯

    SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯

    FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度

    ACQUIRE_CAUSES_WAKEUP:强制使屏幕亮起,这种锁主要针对一些必须通知用户的操作.

    ON_AFTER_RELEASE:当锁被释放时,保持屏幕亮起一段时间

    3、wakelock.acquire(int time)

      此方法会让service或者activity 运行一定时间后又休眠。

    NODE:得加入相应的权限:

    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.DEVICE_POWER"/>

    2 、 AlarmManager闹钟使用

      相关知识网上也很多,这里直接copy一段来自:http://blog.csdn.net/wangxingwu_314/article/details/8060312

    1、AlarmManager,顾名思义,就是“提醒”,是Android中常用的一种系统级别的提示服务,在特定的时刻为我们广播一个指定的Intent。简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为我们广播一个我们设定的Intent,通常我们使用 PendingIntent,PendingIntent可以理解为Intent的封装包,简单的说就是在Intent上在加个指定的动作。在使用Intent的时候,我们还需要在执行startActivity、startService或sendBroadcast才能使Intent有用。而PendingIntent的话就是将这个动作包含在内了。

    定义一个PendingIntent对象。 PendingIntent pi = PendingIntent.getBroadcast(this,0,intent,0);

    2、AlarmManager的常用方法有三个:

    (1)set(int type,long startTime,PendingIntent pi);

    该方法用于设置一次性闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟执行时间,第三个参数表示闹钟响应动作。

    (2)setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);

    该方法用于设置重复闹钟,第一个参数表示闹钟类型,第二个参数表示闹钟首次执行时间,第三个参数表示闹钟两次执行的间隔时间,第三个参数表示闹钟响应动作。

    (3)setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);

    该方法也用于设置重复闹钟,与第二个方法相似,不过其两个闹钟执行的间隔时间不是固定的而已。

    3、三个方法各个参数详悉:

    (1)int type: 闹钟的类型,常用的有5个值:AlarmManager.ELAPSED_REALTIME、 AlarmManager.ELAPSED_REALTIME_WAKEUP、AlarmManager.RTC、 AlarmManager.RTC_WAKEUP、AlarmManager.POWER_OFF_WAKEUP。

    AlarmManager.ELAPSED_REALTIME表示闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3;

    AlarmManager.ELAPSED_REALTIME_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2;

    AlarmManager.RTC表示闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1;

    AlarmManager.RTC_WAKEUP表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0;

    AlarmManager.POWER_OFF_WAKEUP表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;

    (2)long startTime: 闹钟的第一次执行时间,以毫秒为单位,可以自定义时间,不过一般使用当前时间。需要注意的是,本属性与第一个属性(type)密切相关,如果第一个参数对 应的闹钟使用的是相对时间(ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP),那么本属性就得使用相对时间(相对于 系统启动时间来说),比如当前时间就表示为:SystemClock.elapsedRealtime();如果第一个参数对应的闹钟使用的是绝对时间 (RTC、RTC_WAKEUP、POWER_OFF_WAKEUP),那么本属性就得使用绝对时间,比如当前时间就表示 为:System.currentTimeMillis()。

    (3)long intervalTime:对于后两个方法来说,存在本属性,表示两次闹钟执行的间隔时间,也是以毫秒为单位。

    (4)PendingIntent pi: 绑定了闹钟的执行动作,比如发送一个广播、给出提示等等。PendingIntent是Intent的封装类。需要注意的是,如果是通过启动服务来实现闹钟提 示的话,PendingIntent对象的获取就应该采用Pending.getService(Context c,int i,Intent intent,int j)方法;如果是通过广播来实现闹钟提示的话,PendingIntent对象的获取就应该采用 PendingIntent.getBroadcast(Context c,int i,Intent intent,int j)方法;如果是采用Activity的方式来实现闹钟提示的话,PendingIntent对象的获取就应该采用 PendingIntent.getActivity(Context c,int i,Intent intent,int j)方法。如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果。

    3、下面为注册和取消的方法:

    //注册的方法
           Intent i = new Intent(SLEEP_EXPIRED_ACTION);
           AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
           PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
           am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + duration, pi);
    
    //取消的方法
           Intent i = new Intent(SLEEP_EXPIRED_ACTION);
           AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
           PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
           am.cancel(pi);
    
  • 相关阅读:
    每日一水 POJ8道水题
    编译和使用 MySQL C++ Connector
    j2ee model1模型完成分页逻辑的实现 详解!
    DB查询分析器访问EXCEL时,要在表名前后加上中括弧或双引号
    指向结构体变量的指针
    EOSS V3.0 企业运营支撑系统(基于RBAC原理的权限管理)
    MybatisGen1.0 Mybatis JavaBean Mapper生成工具
    The table name must be enclosed in double quotation marks or sqare bracket while accessing EXCEL by
    资源-Android:Android
    软件-开发软件:Android Studio
  • 原文地址:https://www.cnblogs.com/bokeofzp/p/7111760.html
Copyright © 2011-2022 走看看