zoukankan      html  css  js  c++  java
  • Android手机休眠后时间不准确的解决方案(AlarmManager)

    计时的几种方法,在虚拟机中不会出现问题,但是在真机测试中,会遇到这样一种情况: 在手机进行休眠状态后,原来的睡60秒时间,大约变成了睡7分钟左右才再执行.这一直让我很不解,也没有发现代码上有什么问题.

    后来发现别人也遇到了类似的问题. 发现常见的应用中,如游戏,播放器以及控制灯光显示中,都会有这种情况,

    后来通过找了一个资料才知道如果要定时执行的话,要用AlarmManager,这是闹钟服务,Android手机中必须要保证AlarmManager的时钟跟真实时间同步的.所以在 Android手机休眠状态下,AlarmManager时间是不会变慢的. 以下介绍AlarmManager的基本使用.

    AlarmManager简介及使用场景::

    AlarmManager的使用机制有的称呼为全局定时器,有的称呼为闹钟。通过对它的使用,它的作用和Timer有点相似。
    都有两种相似的用法:
    (1)在指定时长后执行某项操作
    (2)周期性的执行某项操作

    AlarmManager对象配合Intent使用,可以定时的开启一个Activity,发送一个BroadCast,或者开启一个Service.

    当你的应用不在运行,而此时你仍然需要你的应用去执行一些操作(比如,短信拦截),只有这种时候才使用AlarmManager, 其他正常情况下的,推荐使用Handler。
    AlarmManager 生命周期:repeating AlarmManager一旦启动就会一直在后台运行(除非执行cancel方法),可以在“应用管理”中看到这个应用状态是正在运行。 “强行停止”可以让Alarmmanager停掉。尝试了几种任务管理器, 都只能重置计数器(确实释放内存了),但都无法关闭定时器,只有系统自带的“强行停止”奏效。

    如果某个AlarmManager已经启动, 程序又再次去启动它,只要PendingIntent是一样,那么之前那个AlarmManager会被release掉。

    AlarmManager 包含的主要方法:
    // 取消已经注册的与参数匹配的定时器
    void cancel(PendingIntent operation)
    //注册一个新的延迟定时器
    void set(int type, long triggerAtTime, PendingIntent operation)
    //注册一个重复类型的定时器
    void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation)
    //注册一个非精密的重复类型定时器
    void setInexactRepeating (int type, long triggerAtTime, long interval, PendingIntent operation)
    //设置时区
    void setTimeZone(String timeZone)

    定时器主要类型:

    public static final int ELAPSED_REALTIME
    // 当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该闹铃所用的时间是相对时间,是从系统启动后开始计时的,包括睡眠时 间,可以通过调用SystemClock.elapsedRealtime()获得。系统值是3 (0x00000003)。

    public static final int ELAPSED_REALTIME_WAKEUP
    //能唤醒系统,用法同ELAPSED_REALTIME,系统值是2 (0x00000002) 。

    public static final int RTC
    //当系统进入睡眠状态时,这种类型的闹铃不会唤醒系统。直到系统下次被唤醒才传递它,该闹铃所用的时间是绝对时间,所用时间是UTC时间,可以通过调用 System.currentTimeMillis()获得。系统值是1 (0x00000001) 。

    public static final int RTC_WAKEUP
    //能唤醒系统,用法同RTC类型,系统值为 0 (0x00000000) 。

    Public static final int POWER_OFF_WAKEUP
    //能唤醒系统,它是一种关机闹铃,就是说设备在关机状态下也可以唤醒系统,所以我们把它称之为关机闹铃。使用方法同RTC类型,系统值为4(0x00000004)。


    如何使用AlarmManager?使用AlarmManager共有三种方式, 都是通过PendingIntent。

    getActivity(Context, int, Intent, int)
    getBroadcast(Context, int, Intent, int)
    getService(Context, int, Intent, int)



    这边就举一个使用BroadCast的例子。
    首先是创建一个BroadCast类,需要继承BroadCastReceiver, 如下:

    /*
     *        Copyright (c) 2011, Yulong Information Technologies
     *        All rights reserved.
     *  
     *  @Project: AlarmTest
     *  @author: Robot        
     */
    package com.yfz;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    
    /**
     * @author Robot
     * @weibo [url]http://weibo.com/feng88724[/url]
     * @date Nov 18, 2011        
     */
    public class ActionBroadCast extends BroadcastReceiver {
            
            private static int num = 0;
            /* (non-Javadoc)
             * @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
             */
            @Override
            public void onReceive(Context context, Intent intent) {
                    // TODO Auto-generated method stub
                    Log.e("ActionBroadCast", "New Message !" + num++);
            }
    
    }
    
    
     now, 3000, pi);
        }
    }

    这边用Repeating的方式。 每隔3秒发一条广播消息过去。RTC_WAKEUP的方式,保证即使手机休眠了,也依然会发广播消息。最后看一下AndroidManifest文件,主要是注册一下Activity和BroadCast。 (实际使用中最好再加个filter,自己定义一个Action比较好)

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.yfz"
        android:versionCode="1"
        android:versionName="1.0" >
    
    <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name" >
            <activity
                android:label="@string/app_name"
                android:name=".AlarmTestActivity" >
         <receiver
                android:name="ActionBroadCast">
                </receiver>
    </activity
    </application>
  • 相关阅读:
    41:和为S的两个数
    40:数组中只出现一次的数字
    39-2:平衡二叉树
    39:二叉树的深度
    38:数字在排序数组中出现的次数
    37:两个链表的第一个公共结点
    36:数组中的逆序对
    35:第一个只出现一次的字符
    34:丑数
    33:把数组排成最小的数
  • 原文地址:https://www.cnblogs.com/xuewater/p/2745201.html
Copyright © 2011-2022 走看看