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.

254 lines
8.7 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)
*
* 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.
*/
/**
* 文件: AlarmAlertActivity.java
* 描述: 便签提醒闹钟弹窗界面
* 作用: 当便签设置的提醒时间到达时,显示提醒对话框并播放闹钟声音
* 功能:
* 1. 在锁屏状态下也能显示提醒
* 2. 播放系统闹钟铃声
* 3. 显示便签内容预览
* 4. 提供快速进入便签编辑的选项
*/
package net.micode.notes.ui;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnDismissListener;
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;
/**
* 便签提醒弹窗活动类
*
* 当便签设置的提醒时间到达时,此活动会被启动,显示提醒对话框并播放闹钟声音。
* 实现了OnClickListener和OnDismissListener接口以处理对话框的交互事件。
*/
public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener {
/** 当前提醒的便签ID */
private long mNoteId;
/** 便签内容摘要 */
private String mSnippet;
/** 便签摘要预览的最大长度 */
private static final int SNIPPET_PREW_MAX_LEN = 60;
/** 媒体播放器,用于播放闹钟声音 */
MediaPlayer mPlayer;
/**
* 活动创建时的回调方法
* 初始化窗口属性、加载便签数据并显示提醒对话框
*
* @param savedInstanceState 保存的实例状态
*/
@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);
}
// 获取启动此活动的意图
Intent intent = getIntent();
try {
// 从URI中提取便签ID
mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1));
// 获取便签内容摘要
mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId);
// 如果摘要过长,截取前面部分并添加省略号
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) {
// 处理参数错误异常
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();
}
/**
* 播放系统闹钟铃声
* 根据系统设置选择合适的音频流类型
*/
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 {
// 设置数据源为闹钟铃声URI
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();
} catch (IOException e) {
// 处理IO异常
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 被点击的按钮ID
*/
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);
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;
}
}
}