/* * 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.java - 闹钟初始化广播接收器 // 主要功能:在设备启动后重新注册所有未触发的便签闹钟提醒 package net.micode.notes.ui; // ======================= 导入区域 ======================= // Android闹钟相关 import android.app.AlarmManager; // 闹钟管理器,用于设置系统闹钟 import android.app.PendingIntent; // 待定意图,用于延迟执行 // Android广播相关 import android.content.BroadcastReceiver; // 广播接收器基类 import android.content.ContentUris; // URI工具,用于构建带ID的URI import android.content.Context; // 上下文 import android.content.Intent; // 意图 // Android数据库相关 import android.database.Cursor; // 数据库查询结果游标 // 应用内部数据模型 import net.micode.notes.data.Notes; // Notes主类 import net.micode.notes.data.Notes.NoteColumns; // 便签表列定义 // ======================= 闹钟初始化广播接收器 ======================= /** * AlarmInitReceiver - 闹钟初始化广播接收器 * 继承自BroadcastReceiver,接收系统启动完成广播 * 主要功能:设备重启后重新注册所有未来的闹钟提醒 * * AndroidManifest.xml中注册: * * * * * */ public class AlarmInitReceiver extends BroadcastReceiver { // ======================= 数据库查询配置 ======================= /** * 查询投影数组 - 指定从数据库查询哪些字段 * 优化查询性能,只获取需要的字段 */ private static final String [] PROJECTION = new String [] { NoteColumns.ID, // 0 - 便签ID,用于构建PendingIntent NoteColumns.ALERTED_DATE // 1 - 提醒时间,用于设置闹钟 }; // 字段索引常量 - 提高代码可读性和维护性 private static final int COLUMN_ID = 0; // ID字段索引 private static final int COLUMN_ALERTED_DATE = 1; // 提醒时间字段索引 // ======================= 广播接收回调方法 ======================= /** * onReceive - 广播接收回调方法 * 当接收到android.intent.action.BOOT_COMPLETED广播时调用 * 执行流程: * 1. 查询所有未来需要提醒的便签 * 2. 为每个便签重新注册系统闹钟 * 3. 关闭数据库游标 * * @param context 广播接收器的上下文 * @param intent 接收到的广播意图(包含BOOT_COMPLETED动作) */ @Override public void onReceive(Context context, Intent intent) { // 1. 获取当前时间戳,用于查询未来提醒 long currentDate = System.currentTimeMillis(); // 2. 查询数据库,获取所有未来需要提醒的便签 // 查询条件:提醒时间 > 当前时间 且 类型为普通便签 Cursor c = context.getContentResolver().query( Notes.CONTENT_NOTE_URI, // 便签表内容URI PROJECTION, // 查询字段:ID和提醒时间 NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE, new String[] { String.valueOf(currentDate) }, // 查询参数:当前时间 null); // 排序方式(null表示默认) // 3. 检查查询结果是否有效 if (c != null) { // 4. 遍历查询结果,为每个便签设置闹钟 if (c.moveToFirst()) { do { // 4.1 获取便签的提醒时间 long alertDate = c.getLong(COLUMN_ALERTED_DATE); // 4.2 创建AlarmReceiver的Intent // AlarmReceiver是实际处理闹钟触发的广播接收器 Intent sender = new Intent(context, AlarmReceiver.class); // 4.3 设置Intent的数据URI,包含便签ID // URI格式:content://micode_notes/note/{noteId} sender.setData(ContentUris.withAppendedId( Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID) )); // 4.4 创建PendingIntent // 参数说明: // - context: 上下文 // - requestCode: 请求码(0表示默认) // - intent: 要执行的Intent // - flags: 标志位(0表示默认) PendingIntent pendingIntent = PendingIntent.getBroadcast( context, 0, sender, 0 ); // 4.5 获取系统闹钟管理器 AlarmManager alarmManager = (AlarmManager) context .getSystemService(Context.ALARM_SERVICE); // 4.6 设置系统闹钟 // 参数说明: // - AlarmManager.RTC_WAKEUP: 使用实时时钟,触发时唤醒设备 // - alertDate: 触发时间(毫秒时间戳) // - pendingIntent: 触发时执行的PendingIntent alarmManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent); } while (c.moveToNext()); // 继续处理下一个便签 } // 5. 关闭游标,释放数据库资源 c.close(); } } }