|
|
/*
|
|
|
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
|
|
|
*
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
* You may obtain a copy of the License at
|
|
|
*
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
*
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
* See the License for the specific language governing permissions and
|
|
|
* limitations under the License.
|
|
|
* 当接收到系统广播时(在AlarmInitReceiver类的onReceive方法中处理广播接收逻辑),首先获取当前系统时间,然后从与笔记相关的内容提供者(通过Notes.CONTENT_NOTE_URI指定)中查询出提醒日期大于当前时间且类型为普通笔记类型的记录,查询结果只获取笔记的ID和提醒日期这两个字段。
|
|
|
对于查询到的每条符合条件的笔记记录,程序会创建一个Intent,将当前笔记的ID附加到指定的Uri上并设置为该Intent的数据部分,接着创建一个对应的PendingIntent用于广播操作,最后获取系统的AlarmManager服务,设置一个基于实时时钟(RTC_WAKEUP类型)的闹钟提醒,当到达提醒日期时,系统会发送广播触发AlarmReceiver(在代码中Intent指定的目标广播接收者类)的相应逻辑,从而实现根据笔记的提醒设置来初始化闹钟提醒功能,确保在合适的时间提醒用户相关笔记的事项。
|
|
|
|
|
|
*onReceive 函数
|
|
|
所属类:AlarmInitReceiver,它继承自 BroadcastReceiver,意味着这个类用于接收系统广播并处理相应逻辑。
|
|
|
功能:
|
|
|
首先获取当前的系统时间(以毫秒为单位,通过 System.currentTimeMillis 方法),将其存储在 currentDate 变量中,这个时间会用于后续的数据库查询条件判断。
|
|
|
使用 context.getContentResolver().query 方法从内容提供者(此处应该是和笔记相关的数据存储,通过 Notes.CONTENT_NOTE_URI 指定查询的数据源)中查询数据。查询的字段通过 PROJECTION 数组指定,只获取笔记的 ID(NoteColumns.ID)和提醒日期(NoteColumns.ALERTED_DATE)这两个字段。查询的筛选条件是提醒日期大于当前日期(NoteColumns.ALERTED_DATE + ">?")并且笔记类型为普通笔记类型(NoteColumns.TYPE + "=" + Notes.TYPE_NOTE),其中当前日期作为参数传入(通过 new String[] { String.valueOf(currentDate) }),排序规则为 null(即不指定排序)。
|
|
|
接着判断查询得到的游标 c 是否为 null,如果不为 null,则进一步判断游标是否能移动到第一条记录(通过 moveToFirst 方法),若可以,进入循环(do-while 循环,通过 moveToNext 方法判断是否还有下一条记录来决定循环是否继续)。在循环内:
|
|
|
获取当前记录对应的提醒日期(通过 c.getLong(COLUMN_ALERTED_DATE) 获取对应列的值)。
|
|
|
创建一个新的 Intent,指定其目标广播接收者为 AlarmReceiver 类(意味着后续会将这个 Intent 作为广播发送给 AlarmReceiver 处理相关逻辑),并通过 ContentUris.withAppendedId 方法将当前笔记的 ID 附加到 Notes.CONTENT_NOTE_URI 上,设置为这个 Intent 的数据部分,用于传递具体是哪个笔记的相关信息。
|
|
|
根据这个 Intent 创建一个 PendingIntent,它可以看作是一种延迟执行或者在特定条件下执行的 Intent,此处使用 PendingIntent.getBroadcast 方法,表明这是一个用于广播的 PendingIntent,并且设置请求码为 0 等相关参数。
|
|
|
获取系统的 AlarmManager 服务(通过 context.getSystemService(Context.ALARM_SERVICE)),然后使用 set 方法设置一个闹钟提醒,闹钟类型为 RTC_WAKEUP(表示在指定的绝对时间唤醒设备来触发提醒,基于实时时钟),提醒时间为之前获取的 alertDate,触发的 PendingIntent 就是刚刚创建的那个,这样当到达指定提醒时间时,系统就会发送广播触发 AlarmReceiver 对应的逻辑。
|
|
|
最后,如果游标 c 不为 null,在处理完所有符合条件的记录后,通过 c.close 方法关闭游标,释放相关资源,避免内存泄漏等问题。
|
|
|
关于 PROJECTION 数组相关常量
|
|
|
功能说明:
|
|
|
PROJECTION 数组定义了查询数据库时要获取的字段列表,这里明确指定只获取笔记的 ID(对应 NoteColumns.ID)和提醒日期(对应 NoteColumns.ALERTED_DATE)这两个字段,用于后续在循环中获取相应数据来设置闹钟提醒等操作。
|
|
|
COLUMN_ID 和 COLUMN_ALERTED_DATE 这两个常量分别定义了在查询结果游标中对应字段的索引位置,方便后续通过游标获取对应列的值,例如 c.getLong(COLUMN_ALERTED_DATE) 就是按照这个定义好的索引位置准确获取提醒日期字段的值,代码结构上更加清晰和便于维护,避免直接使用硬编码的索引数字。
|
|
|
*/
|
|
|
|
|
|
package net.micode.notes.ui;
|
|
|
|
|
|
import android.app.AlarmManager;
|
|
|
import android.app.PendingIntent;
|
|
|
import android.content.BroadcastReceiver;
|
|
|
import android.content.ContentUris;
|
|
|
import android.content.Context;
|
|
|
import android.content.Intent;
|
|
|
import android.database.Cursor;
|
|
|
|
|
|
import net.micode.notes.data.Notes;
|
|
|
import net.micode.notes.data.Notes.NoteColumns;
|
|
|
|
|
|
|
|
|
public class AlarmInitReceiver extends BroadcastReceiver {
|
|
|
|
|
|
private static final String [] PROJECTION = new String [] {
|
|
|
NoteColumns.ID,
|
|
|
NoteColumns.ALERTED_DATE
|
|
|
};
|
|
|
|
|
|
private static final int COLUMN_ID = 0;
|
|
|
private static final int COLUMN_ALERTED_DATE = 1;
|
|
|
|
|
|
@Override
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
long currentDate = System.currentTimeMillis();
|
|
|
Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI,
|
|
|
PROJECTION,
|
|
|
NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE,
|
|
|
new String[] { String.valueOf(currentDate) },
|
|
|
null);
|
|
|
|
|
|
if (c != null) {
|
|
|
if (c.moveToFirst()) {
|
|
|
do {
|
|
|
long alertDate = c.getLong(COLUMN_ALERTED_DATE);
|
|
|
Intent sender = new Intent(context, AlarmReceiver.class);
|
|
|
sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID)));
|
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0);
|
|
|
AlarmManager alermManager = (AlarmManager) context
|
|
|
.getSystemService(Context.ALARM_SERVICE);
|
|
|
alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent);
|
|
|
} while (c.moveToNext());
|
|
|
}
|
|
|
c.close();
|
|
|
}
|
|
|
}
|
|
|
}
|