You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MiNote/ui/AlarmAlertActivity.java

198 lines
8.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* 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; // 置空引用防止重复操作
}
}
}