原文地址:不详
前面介绍的时间服务的作用域都是应用程序,也就是说,将当前的应用程序关闭后,时间服务就会停止。但在很多时候,需要时间服务不依赖应用程序而存在。也就是说,虽然是应用程序启动的服务,但即使将应用程序关闭,服务仍然可以正常运行。
为了达到服务与应用程序独立的目的,需要获得AlarmManager对象。该对象需要通过如下代码获得:
- AlarmManager alarmManager = (AlarmManager)
getSystemService(Context.ALARM_SERVICE);
AlarmManager类的一个非常重要的方法是setRepeating,通过该方法,可以设置执行时间间隔和相应的动作。setRepeating方法的定义如下:
- public void setRepeating(int type, long triggerAtTime,
long interval, PendingIntent operation);
setRepeating方法有4个参数,这些参数的含义如下:
type:表示警报类型,一般可以取的值是AlarmManager.RTC和AlarmManager.RTC_WAKEUP。如果将type参数值设为AlarmManager.RTC,表示是一个正常的定时器,如果将type参数值设为AlarmManager.RTC_WAKEUP,除了有定时器的功能外,还会发出警报声(例如,响铃、震动)。
triggerAtTime:第1次运行时要等待的时间,也就是执行延迟时间,单位是毫秒。
interval:表示执行的时间间隔,单位是毫秒。
operation:一个PendingIntent对象,表示到时间后要执行的操作。PendingIntent与Intent类似,可以封装Activity、BroadcastReceiver和Service。但与Intent不同的是,PendingIntent可以脱离应用程序而存在。
从setRepeating方法的4个参数可以看出,使用setRepeating方法最重要的就是创建PendingIntent对象。例如,在下面的代码中用PendingIntent指定了一个Activity。
- Intent intent = new Intent(this, MyActivity.class);
- PendingIntent pendingActivityIntent = PendingIntent.
getActivity(this, 0,intent, 0);
在创建完PendingIntent对象后,就可以使用setRepeating方法设置定时器了,代码如下:
- AlarmManager alarmManager = (AlarmManager)
getSystemService(Context.ALARM_SERVICE);- alarmManager.setRepeating(AlarmManager.RTC,
0, 5000, pendingActivityIntent);
执行上面的代码,即使应用程序关闭后,每隔5秒,系统仍然会显示MyActivity。如果要取消定时器,可以使用如下代码:
- alarmManager.cancel(pendingActivityIntent);
运行本节的例子,界面如图8.20所示。单击【GetActivity】按钮,然后关闭当前应用程序,会发现系统5秒后会显示MyActivity。关闭MyActivity后,在5秒后仍然会再次显示MyActivity。
本节只介绍了如何用PendingIntent来指定Activity,读者在实例50和实例51中将会看到利用BroadcastReceiver和Service执行定时任务。
实例50:定时更换壁纸
工程目录:src\ch08\ch08_changewallpaper
使用AlarmManager可以实现很多有趣的功能。本例中将实现一个可以定时更换手机壁纸的程序。在编写代码之前,先来看一下如图8.21所示的效果。单击【定时更换壁纸】按钮后,手机的壁纸会每隔5秒变换一次。
本例使用Service来完成更换壁纸的工作,下面先编写一个Service类,代码如下:
- package net.blogjava.mobile;
- import java.io.InputStream;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- public class ChangeWallpaperService extends Service
- {
- private static int index = 0;
- // 保存res\raw目录中图像资源的ID
- private int[] resIds = new int[]{ R.raw.wp1,
R.raw.wp2, R.raw.wp3, R.raw.wp4, R.raw.wp5};- @Override
- public void onStart(Intent intent, int startId)
- {
- if(index == 5)
- index = 0;
- // 获得res\raw目录中图像资源的InputStream对象
- InputStream inputStream = getResources().
openRawResource(resIds[index++]);- try
- {
- // 更换壁纸
- setWallpaper(inputStream);
- }
- catch (Exception e)
- {
- }
- super.onStart(intent, startId);
- }
- @Override
- public void onCreate()
- {
- super.onCreate();
- }
- @Override
- public IBinder onBind(Intent intent)
- {
- return null;
- }
- }