/*
 * 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();
        }
    }
}
