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.
2Q1/ui/AlarmAlertActivity.java

213 lines
11 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.
*/
// 包声明表明该类所在的包名此处在net.micode.notes.ui包下
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;
// AlarmAlertActivity类继承自Activity类实现了OnClickListener和OnDismissListener接口用于处理闹钟提醒相关的界面展示、声音播放等功能
public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener {
// 记录笔记的ID用于后续操作中标识具体的笔记
private long mNoteId;
// 笔记的摘要内容,用于在提醒对话框中展示部分笔记内容
private String mSnippet;
// 定义摘要预览的最大长度为60个字符
private static final int SNIPPET_PREW_MAX_LEN = 60;
// 用于播放闹钟提醒声音的MediaPlayer对象
MediaPlayer mPlayer;
// 重写Activity的onCreate方法在Activity创建时被调用进行一些初始化操作
@Override
protected void onCreate(Bundle savedInstanceState) {
// 调用父类的onCreate方法完成Activity创建的基本初始化流程这是必须的操作
super.onCreate(savedInstanceState);
// 请求去除Activity的标题栏使界面更加简洁通常用于全屏等特定显示需求
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 获取当前Activity的窗口对象后续用于设置窗口相关的属性
final Window win = getWindow();
// 给窗口添加标志位使得在屏幕锁定时也能显示该Activity方便用户看到闹钟提醒
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);
}
// 获取启动该Activity的Intent对象用于获取传递过来的数据等信息
Intent intent = getIntent();
try {
// 从Intent携带的数据中获取笔记的ID具体是从数据的路径片段中的第二个元素获取假设数据格式符合特定规范
mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1));
// 通过工具类DataUtils根据笔记ID获取笔记的摘要内容
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) {
// 如果在获取笔记ID或处理摘要过程中出现参数异常打印异常堆栈信息并且直接返回不再继续执行后续可能出错的操作
e.printStackTrace();
return;
}
// 创建一个MediaPlayer对象用于播放闹钟提醒的声音
mPlayer = new MediaPlayer();
// 判断该笔记是否在笔记数据库中可见通过DataUtils工具类的方法进行判断
if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) {
// 如果可见,展示操作对话框,给用户提供相关操作选项
showActionDialog();
// 调用方法播放闹钟提醒声音
playAlarmSound();
} else {
// 如果笔记不可见直接结束该Activity不需要进行后续的提醒相关操作
finish();
}
}
// 方法用于判断屏幕是否处于开启状态通过获取PowerManager服务并调用其isScreenOn方法来判断
private boolean isScreenOn() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
return pm.isScreenOn();
}
// 方法用于播放闹钟提醒声音,进行一系列设置并启动声音播放
private void playAlarmSound() {
// 获取系统默认的闹钟铃声的Uri通过RingtoneManager来获取实际使用的默认铃声的Uri
Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
// 获取系统设置中受静音模式影响的音频流相关设置,用于后续判断闹钟音频流的设置情况
int silentModeStreams = Settings.System.getInt(getContentResolver(),
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
// 判断静音模式下是否影响闹钟音频流如果受影响则按照相应设置设置MediaPlayer的音频流类型
if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM))!= 0) {
mPlayer.setAudioStreamType(silentModeStreams);
} else {
// 如果不受影响将MediaPlayer的音频流类型设置为普通的闹钟音频流类型
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
}
try {
// 设置MediaPlayer的数据源为获取到的闹钟铃声的Uri指定从哪里获取音频数据来播放
mPlayer.setDataSource(this, url);
// 准备MediaPlayer使其进入可播放状态加载音频数据等资源
mPlayer.prepare();
// 设置MediaPlayer循环播放使得闹钟声音一直响直到被用户操作停止
mPlayer.setLooping(true);
// 启动MediaPlayer开始播放闹钟声音
mPlayer.start();
} catch (IllegalArgumentException e) {
// 如果在设置数据源等操作中出现参数异常,打印异常堆栈信息
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// 如果出现安全相关异常,比如没有权限访问音频资源等情况,打印异常堆栈信息
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// 如果MediaPlayer处于不正确的状态比如已经在播放等情况导致操作失败打印异常堆栈信息
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// 如果在读取音频数据等操作中出现IO异常比如文件不存在等情况打印异常堆栈信息
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 方法用于展示操作对话框,给用户提供针对闹钟提醒的操作选项,比如确认、进入编辑等
private void showActionDialog() {
// 创建一个AlertDialog的构建器用于构建自定义的对话框
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
// 设置对话框的标题为应用的名称,通过资源文件中的字符串资源来设置
dialog.setTitle(R.string.app_name);
// 设置对话框的消息内容为前面获取和处理后的笔记摘要内容,展示给用户提醒相关的笔记信息
dialog.setMessage(mSnippet);
// 设置对话框的确认按钮通常是正向操作按钮的文本及点击监听器点击时会触发OnClickListener中的相应逻辑
dialog.setPositiveButton(R.string.notealert_ok, this);
// 判断屏幕是否开启,如果开启,设置对话框的取消按钮(通常是进入相关操作按钮)的文本及点击监听器
if (isScreenOn()) {
dialog.setNegativeButton(R.string.notealert_enter, this);
}
// 构建并显示对话框,同时给对话框设置关闭监听器,当对话框关闭时会触发相应逻辑
dialog.show().setOnDismissListener(this);
}
// 实现OnClickListener接口的方法处理对话框按钮点击事件根据点击的按钮执行相应的操作
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_NEGATIVE:
// 如果点击的是取消按钮通常是进入相关操作按钮创建一个Intent用于启动笔记编辑Activity
Intent intent = new Intent(this, NoteEditActivity.class);
// 设置Intent的动作这里设置为查看动作表明是查看笔记详情的意图
intent.setAction(Intent.ACTION_VIEW);
// 将笔记的ID作为额外数据添加到Intent中传递给NoteEditActivity以便其能识别要编辑的具体笔记
intent.putExtra(Intent.EXTRA_UID, mNoteId);
// 启动NoteEditActivity切换到笔记编辑界面
startActivity(intent);
break;
default:
break;
}
}
// 实现OnDismissListener接口的方法当对话框关闭时被调用用于停止闹钟声音并结束当前Activity
public void onDismiss(DialogInterface dialog) {
// 调用方法停止闹钟声音,释放相关资源
stopAlarmSound();
// 结束当前Activity关闭闹钟提醒界面
finish();
}
// 方法用于停止闹钟声音释放MediaPlayer相关的资源将其设置为null
private void stopAlarmSound() {
if (mPlayer!= null) {
// 停止MediaPlayer的播放
mPlayer.stop();
// 释放MediaPlayer占用的资源如音频缓冲区等
mPlayer.release();
// 将MediaPlayer对象设置为null避免后续误操作
mPlayer = null;
}
}
}