|
|
|
|
|
/*
|
|
|
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
|
|
|
*
|
|
|
* 版权声明:本文件由MiCode开源社区开发,遵循Apache License, Version 2.0协议;
|
|
|
* 您仅在遵守协议的前提下使用本文件,完整协议可通过以下链接获取:
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
* 注:未书面明确要求时,本软件按"原样"提供,不附带任何明示或暗示的保证。
|
|
|
*/
|
|
|
|
|
|
package net.micode.notes.ui;
|
|
|
|
|
|
import android.app.Activity;
|
|
|
import android.app.AlertDialog;
|
|
|
import android.content.Context;
|
|
|
import android.content.DialogInterface;
|
|
|
import android.content.Intent;
|
|
|
import android.media.AudioManager;
|
|
|
import android.media.MediaPlayer;
|
|
|
import android.media.RingtoneManager;
|
|
|
import android.net.Uri;
|
|
|
import android.os.Bundle;
|
|
|
import android.os.PowerManager;
|
|
|
import android.provider.Settings;
|
|
|
import android.view.Window;
|
|
|
import android.view.WindowManager;
|
|
|
|
|
|
import net.micode.notes.R;
|
|
|
import net.micode.notes.data.Notes;
|
|
|
import net.micode.notes.tool.DataUtils;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
|
/**
|
|
|
* 闹钟提醒活动类
|
|
|
* 功能:当笔记的闹钟提醒触发时,通过对话框提示用户,并播放闹钟声音
|
|
|
* 实现逻辑:处理窗口显示、闹钟声音播放、用户交互(确认/进入笔记编辑)
|
|
|
*/
|
|
|
public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener {
|
|
|
private long mNoteId; // 当前提醒对应的笔记ID
|
|
|
private String mSnippet; // 当前笔记的摘要内容(用于提醒显示)
|
|
|
private static final int SNIPPET_PREW_MAX_LEN = 60; // 摘要预览的最大长度(超过则截断)
|
|
|
MediaPlayer mPlayer; // 媒体播放器实例(用于播放闹钟声音)
|
|
|
|
|
|
@Override
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
super.onCreate(savedInstanceState);
|
|
|
// 请求无标题窗口(提升提醒界面的专注度)
|
|
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
|
|
|
|
final Window win = getWindow();
|
|
|
// 添加窗口标志:锁屏时显示提醒(确保用户能看到闹钟)
|
|
|
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
|
|
|
|
|
|
// 如果屏幕未点亮,则添加唤醒屏幕相关标志(确保用户被提醒唤醒)
|
|
|
if (!isScreenOn()) {
|
|
|
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON // 保持屏幕常亮
|
|
|
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON // 点亮屏幕
|
|
|
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON // 允许屏幕锁定时显示
|
|
|
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); // 布局插入装饰(适配不同设备)
|
|
|
}
|
|
|
|
|
|
// 从启动意图中解析笔记ID和摘要内容
|
|
|
Intent intent = getIntent();
|
|
|
try {
|
|
|
// 从Uri路径中获取笔记ID(格式示例:content://.../notes/123 → 取路径段的第二个元素)
|
|
|
mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1));
|
|
|
// 通过DataUtils工具类获取笔记摘要
|
|
|
mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId);
|
|
|
// 截断过长的摘要(超过60字符时显示前60字符+省略号)
|
|
|
mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN
|
|
|
? mSnippet.substring(0, SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info)
|
|
|
: mSnippet;
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
// 解析失败时打印异常并结束活动(无效的笔记ID)
|
|
|
e.printStackTrace();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 初始化媒体播放器
|
|
|
mPlayer = new MediaPlayer();
|
|
|
// 检查笔记是否在数据库中可见(非回收站且类型正确)
|
|
|
if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) {
|
|
|
// 显示提醒对话框并播放闹钟声音
|
|
|
showActionDialog();
|
|
|
playAlarmSound();
|
|
|
} else {
|
|
|
// 笔记不可见时直接结束活动(可能已被删除)
|
|
|
finish();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 检查屏幕是否处于点亮状态
|
|
|
* @return 屏幕点亮返回true,否则返回false
|
|
|
*/
|
|
|
private boolean isScreenOn() {
|
|
|
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
|
|
return pm.isScreenOn(); // 通过PowerManager获取屏幕状态
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 播放闹钟声音(使用系统默认闹钟铃声)
|
|
|
*/
|
|
|
private void playAlarmSound() {
|
|
|
// 获取系统默认的闹钟铃声Uri
|
|
|
Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
|
|
|
|
|
|
// 获取系统设置中受静音模式影响的音频流(处理静音模式下的闹钟播放)
|
|
|
int silentModeStreams = Settings.System.getInt(getContentResolver(),
|
|
|
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
|
|
|
|
|
|
// 根据静音模式设置音频流类型(优先使用受影响的流,否则使用默认闹钟流)
|
|
|
if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) {
|
|
|
mPlayer.setAudioStreamType(silentModeStreams);
|
|
|
} else {
|
|
|
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
// 设置铃声数据源(系统默认闹钟铃声)
|
|
|
mPlayer.setDataSource(this, url);
|
|
|
// 同步准备播放器(确保资源加载完成)
|
|
|
mPlayer.prepare();
|
|
|
// 设置循环播放(持续提醒直到用户操作)
|
|
|
mPlayer.setLooping(true);
|
|
|
// 开始播放
|
|
|
mPlayer.start();
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
e.printStackTrace(); // 参数错误异常处理
|
|
|
} catch (SecurityException e) {
|
|
|
e.printStackTrace(); // 安全权限异常处理(如未获取读取铃声权限)
|
|
|
} catch (IllegalStateException e) {
|
|
|
e.printStackTrace(); // 播放器状态异常处理(如重复调用start)
|
|
|
} catch (IOException e) {
|
|
|
e.printStackTrace(); // 输入输出异常处理(铃声文件不存在)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 显示闹钟提醒对话框(包含笔记摘要和操作按钮)
|
|
|
*/
|
|
|
private void showActionDialog() {
|
|
|
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
|
|
dialog.setTitle(R.string.app_name); // 对话框标题为应用名称
|
|
|
dialog.setMessage(mSnippet); // 对话框内容为笔记摘要
|
|
|
dialog.setPositiveButton(R.string.notealert_ok, this); // 确定按钮(关闭提醒)
|
|
|
|
|
|
// 如果屏幕已点亮,添加"进入"按钮(跳转到笔记编辑界面)
|
|
|
if (isScreenOn()) {
|
|
|
dialog.setNegativeButton(R.string.notealert_enter, this);
|
|
|
}
|
|
|
|
|
|
// 显示对话框并设置关闭监听器(对话框关闭时触发后续操作)
|
|
|
dialog.show().setOnDismissListener(this);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 对话框按钮点击事件处理
|
|
|
* @param dialog 触发事件的对话框
|
|
|
* @param which 被点击的按钮类型(如BUTTON_NEGATIVE)
|
|
|
*/
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
switch (which) {
|
|
|
case DialogInterface.BUTTON_NEGATIVE: // "进入"按钮点击
|
|
|
// 启动笔记编辑活动(查看或编辑当前提醒的笔记)
|
|
|
Intent intent = new Intent(this, NoteEditActivity.class);
|
|
|
intent.setAction(Intent.ACTION_VIEW); // 设置操作为查看
|
|
|
intent.putExtra(Intent.EXTRA_UID, mNoteId); // 传递笔记ID
|
|
|
startActivity(intent);
|
|
|
break;
|
|
|
default: // 其他按钮(如确定按钮)不做额外处理
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 对话框关闭时的回调(无论通过按钮还是其他方式关闭)
|
|
|
* @param dialog 关闭的对话框
|
|
|
*/
|
|
|
public void onDismiss(DialogInterface dialog) {
|
|
|
// 停止闹钟声音并释放资源
|
|
|
stopAlarmSound();
|
|
|
// 结束当前活动
|
|
|
finish();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 停止闹钟声音并释放媒体播放器资源
|
|
|
*/
|
|
|
private void stopAlarmSound() {
|
|
|
if (mPlayer != null) {
|
|
|
mPlayer.stop(); // 停止播放
|
|
|
mPlayer.release(); // 释放播放器资源(避免内存泄漏)
|
|
|
mPlayer = null; // 置空引用防止重复操作
|
|
|
}
|
|
|
}
|
|
|
} |