如果PendingIntent的flag用的FLAG_UPDATE_CURRENT,那一个新的闹钟任务不是会把旧的待响的闹钟任务更新掉吗?
关于PendingIntent的flag设置请看这里
解决思路:设定闹钟的服务先把所有要设定的闹钟信息,按时间的先后存储起来。并先设定时间最近的一个闹钟。当一个闹钟触发后,发送一个消息给设定闹钟的服务,服务得到消息后,再设定下一个闹钟,循环这一步,直到所有闹钟设定完成。
重点:闹钟触发后,怎么发送消息。以及在服务里如何接受消息。
以下贴出主要代码,已有注释:
Reminder类实现Comparable接口,重写compareTo方法,以排序。
public class Reminder implements Parcelable ,Comparable{//Parcelable接口是为了实现在传递此类型的数据,具体用法在此不多作介绍。
private Date time;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(time.getTime());
}
public static final Parcelable.Creator<Reminder> CREATOR = new Parcelable.Creator<Reminder>() {
public Reminder createFromParcel(Parcel in) {
return new Reminder(in);
}
public Reminder[] newArray(int size) {
return new Reminder[size];
}
};
private Reminder(Parcel in) {
time = new Date(in.readLong());
}
@Override
public int compareTo(Object o) {
if (o instanceof Reminder)//以Reminder的时间先后来排序
return (int)(time.getTime()-((Reminder) o).getTime().getTime());
return 0;
}
public class MainService extends Service {
Intent intent;
ArrayList<Reminder> remAList;
MainServReceiver receiver;
public static final String rece_action = "com.lsto.action.SERVRE_ACTION";
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
// 代码方式注册BroadcastReceiver
receiver = new MainServReceiver();
IntentFilter filter = new IntentFilter(rece_action);
registerReceiver(receiver, filter);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
ArrayList<Reminder> aList = intent
.getParcelableArrayListExtra(Reminder.ARRAYKEY);
if (aList != null) {
remAList = (ArrayList<Reminder>) aList.clone();
Collections.sort(remAList);//按Reminder的时间先后升序排序
for (int i = 0; i < remAList.size(); i++) {
if (remAList.get(i).isPastDue())
remAList.remove(i);
}
setOneAlarm();
}
return START_STICKY;
}
/**
* 从排好序的List中获取第一个元素作为闹钟的信息,并设定一个闹钟服务。设定好后,从List中移除这个元素
*/
private void setOneAlarm() {
if (remAList.size() == 0)
return;
Reminder Rem = remAList.get(0);
// 闹钟服务用来启动通知服务
Intent intent = new Intent();
intent.setAction("com.lsto.SERV_NOTIFY");
intent.putExtra(Reminder.KEY, Rem);
PendingIntent piServ = PendingIntent.getService(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager aMan = (AlarmManager) getSystemService(Service.ALARM_SERVICE);
aMan.set(AlarmManager.RTC_WAKEUP, Rem.getTime().getTime(), piServ);
remAList.remove(0);
}
//内部类继承BroadcastReceiver,接收到广播消息后,会回调实现的onReceive方法。在此该方法实现设定一个闹钟服务。
public class MainServReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
setOneAlarm();
}
}
}
通知服务类部分代码,给系统的通知栏中发送消息,具体方法在此不多作解释。
public class NotifyServ extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId) {
Reminder rem = intent.getParcelableExtra(Reminder.KEY);
setNotifyFromRem(rem);
//发送广播消息,通知主服务设定下一个闹钟
Intent sendIntent = new Intent(MainService.rece_action);
sendBroadcast(sendIntent);
return START_STICKY;
}
...
...
...
}
本例已通过测试,但不知道什么原因,在LogCat中报以下错误,不过不影响正常使用。
04-21 20:46:21.256: E/ActivityThread(13926): Service com.lsto.MainService has leaked IntentReceiver com.lsto.MainService$MainServReceiver@4066cc68 that was originally registered here. Are you missing a call to unregisterReceiver()?
04-21 20:46:21.256: E/ActivityThread(13926): android.app.IntentReceiverLeaked: Service com.lsto.MainService has leaked IntentReceiver com.lsto.MainService$MainServReceiver@4066cc68 that was originally registered here. Are you missing a call to unregisterReceiver()?
总结—BroadcastReceiver的使用方法:
第一步,定义一个类继承BroadcastReceiver类,并实现onReceiver方法,这个方法就类似于监听器,一监听到有广播发出,就会被调用
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
第二步,指定匹配的Intent,不过有两种方式:
1.使用代码的方式
MyReceiver receiver = new MyReceiver();
IntentFilter filter = new IntentFilter("android.demo.MYRECEIVED");
registerReceiver(receiver, filter);
2.类似Activity和Service的方式,配置AndroidManifest.xml
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.demo.MYRECEIVED"/>
</intent-filter>
</receiver>
第三步,发送广播
Intent sendIntent = new Intent("android.demo.MYRECEIVED");
sendBroadcast(sendIntent);