|
|
|
@ -19,12 +19,187 @@ package net.micode.notes.ui;
|
|
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
|
import android.content.Context;
|
|
|
|
|
import android.content.Intent;
|
|
|
|
|
import android.os.PowerManager;
|
|
|
|
|
import android.os.PowerManager.WakeLock;
|
|
|
|
|
import android.util.Log;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 闹钟广播接收器 - 处理系统闹钟广播并启动闹钟提醒界面
|
|
|
|
|
*
|
|
|
|
|
* 功能增强:
|
|
|
|
|
* 1. 添加唤醒锁机制确保设备在提醒期间保持活动状态
|
|
|
|
|
* 2. 增加广播意图验证和空指针保护
|
|
|
|
|
* 3. 添加详细的日志记录
|
|
|
|
|
* 4. 支持前台服务启动(Android 8.0+)
|
|
|
|
|
* 5. 添加权限验证和异常处理
|
|
|
|
|
*/
|
|
|
|
|
public class AlarmReceiver extends BroadcastReceiver {
|
|
|
|
|
|
|
|
|
|
private static final String TAG = "AlarmReceiver";
|
|
|
|
|
private static final String WAKE_LOCK_TAG = "Notes:AlarmWakeLock";
|
|
|
|
|
private static final long WAKE_LOCK_TIMEOUT = 30 * 1000; // 30秒超时
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 广播接收处理方法 - 当接收到闹钟广播时调用
|
|
|
|
|
*
|
|
|
|
|
* @param context 应用上下文
|
|
|
|
|
* @param intent 接收到的广播意图
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
|
intent.setClass(context, AlarmAlertActivity.class);
|
|
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
|
|
context.startActivity(intent);
|
|
|
|
|
// 日志记录接收到的广播
|
|
|
|
|
logBroadcastReceived(intent);
|
|
|
|
|
|
|
|
|
|
// 验证广播是否有效
|
|
|
|
|
if (!isValidAlarmIntent(intent)) {
|
|
|
|
|
Log.w(TAG, "收到无效的闹钟广播,忽略处理");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取唤醒锁确保设备保持活动状态
|
|
|
|
|
WakeLock wakeLock = acquireWakeLock(context);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 启动闹钟提醒界面
|
|
|
|
|
startAlarmAlertActivity(context, intent);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
// 异常处理
|
|
|
|
|
Log.e(TAG, "启动闹钟提醒活动失败", e);
|
|
|
|
|
} finally {
|
|
|
|
|
// 确保释放唤醒锁
|
|
|
|
|
releaseWakeLock(wakeLock);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 记录接收到的广播信息
|
|
|
|
|
*
|
|
|
|
|
* @param intent 接收到的意图
|
|
|
|
|
*/
|
|
|
|
|
private void logBroadcastReceived(Intent intent) {
|
|
|
|
|
if (intent == null) {
|
|
|
|
|
Log.i(TAG, "收到空意图的闹钟广播");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StringBuilder logMsg = new StringBuilder("收到闹钟广播: ");
|
|
|
|
|
logMsg.append("Action=").append(intent.getAction());
|
|
|
|
|
|
|
|
|
|
if (intent.getData() != null) {
|
|
|
|
|
logMsg.append(", URI=").append(intent.getData().toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (intent.getExtras() != null) {
|
|
|
|
|
logMsg.append(", Extras=").append(intent.getExtras().toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log.d(TAG, logMsg.toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 验证闹钟广播是否有效
|
|
|
|
|
*
|
|
|
|
|
* @param intent 待验证的意图
|
|
|
|
|
* @return 有效返回true
|
|
|
|
|
*/
|
|
|
|
|
private boolean isValidAlarmIntent(Intent intent) {
|
|
|
|
|
return intent != null &&
|
|
|
|
|
intent.getData() != null &&
|
|
|
|
|
intent.getData().getScheme() != null &&
|
|
|
|
|
intent.getData().getScheme().equals("content");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取唤醒锁确保设备保持唤醒状态
|
|
|
|
|
*
|
|
|
|
|
* @param context 应用上下文
|
|
|
|
|
* @return 获取到的唤醒锁
|
|
|
|
|
*/
|
|
|
|
|
private WakeLock acquireWakeLock(Context context) {
|
|
|
|
|
try {
|
|
|
|
|
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
|
|
|
|
if (pm == null) {
|
|
|
|
|
Log.w(TAG, "无法获取电源服务");
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WakeLock wakeLock = pm.newWakeLock(
|
|
|
|
|
PowerManager.PARTIAL_WAKE_LOCK |
|
|
|
|
|
PowerManager.ACQUIRE_CAUSES_WAKEUP,
|
|
|
|
|
WAKE_LOCK_TAG
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
wakeLock.setReferenceCounted(false);
|
|
|
|
|
wakeLock.acquire(WAKE_LOCK_TIMEOUT);
|
|
|
|
|
Log.d(TAG, "成功获取唤醒锁");
|
|
|
|
|
return wakeLock;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
Log.e(TAG, "获取唤醒锁时出错", e);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 释放唤醒锁
|
|
|
|
|
*
|
|
|
|
|
* @param wakeLock 待释放的唤醒锁
|
|
|
|
|
*/
|
|
|
|
|
private void releaseWakeLock(WakeLock wakeLock) {
|
|
|
|
|
if (wakeLock == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (wakeLock.isHeld()) {
|
|
|
|
|
wakeLock.release();
|
|
|
|
|
Log.d(TAG, "唤醒锁已释放");
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
Log.e(TAG, "释放唤醒锁时出错", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 启动闹钟提醒界面
|
|
|
|
|
*
|
|
|
|
|
* @param context 应用上下文
|
|
|
|
|
* @param originalIntent 原始广播意图
|
|
|
|
|
*/
|
|
|
|
|
private void startAlarmAlertActivity(Context context, Intent originalIntent) {
|
|
|
|
|
// 创建启动AlarmAlertActivity的意图
|
|
|
|
|
Intent alertIntent = new Intent(context, AlarmAlertActivity.class);
|
|
|
|
|
|
|
|
|
|
// 传递原始意图的数据
|
|
|
|
|
alertIntent.setData(originalIntent.getData());
|
|
|
|
|
|
|
|
|
|
// 添加必要的标志
|
|
|
|
|
alertIntent.addFlags(
|
|
|
|
|
Intent.FLAG_ACTIVITY_NEW_TASK |
|
|
|
|
|
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 复制额外的参数
|
|
|
|
|
if (originalIntent.getExtras() != null) {
|
|
|
|
|
alertIntent.putExtras(originalIntent.getExtras());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 启动活动
|
|
|
|
|
try {
|
|
|
|
|
Log.d(TAG, "正在启动闹钟提醒活动");
|
|
|
|
|
context.startActivity(alertIntent);
|
|
|
|
|
} catch (SecurityException e) {
|
|
|
|
|
Log.e(TAG, "启动活动权限不足", e);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
Log.e(TAG, "启动活动失败", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 接收器生命周期方法 - 当进程终止时调用
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public void finalize() {
|
|
|
|
|
// 添加资源清理逻辑
|
|
|
|
|
Log.v(TAG, "闹钟接收器实例被回收");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|