Android手机休眠后时间不准确的解决方案

长平狐 发布于 2012/09/03 12:29
阅读 5K+
收藏 0

Linux基金会免费官方培训及考试申请即将截止,戳这里申请!>>>

上一篇讲到了计时的几种方法,在虚拟机中不会出现问题,但是在真机测试中,会遇到这样一种情况: 在手机进行休眠状态后,原来的睡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掉。

AlamManager具体方法及属性详解:

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>

其他用法以后待有时间补上,有部分内容可能不太准备,欢迎大家帮忙补充



原文链接:http://blog.csdn.net/t12x3456/article/details/7826811
加载中
返回顶部
顶部