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.
test1/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java

220 lines
13 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类意味着它是一个安卓中的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) {
super.onCreate(savedInstanceState);
// 请求去除Activity的标题栏使界面更加简洁仅在支持该特性的安卓版本和设备上生效
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 获取当前Activity的窗口对象后续用于设置窗口的各种属性
final Window win = getWindow();
// 设置窗口属性,使窗口在屏幕锁定时也能够显示出来,方便用户看到提醒信息
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
// 调用isScreenOn方法判断屏幕是否处于开启状态如果屏幕未开启
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 intent = getIntent();
try {
// 从Intent携带的数据中解析出笔记的ID具体是从Intent的数据Uri的路径段中获取第二个元素索引为1并转换为长整型
mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1));
// 通过DataUtils工具类的方法根据笔记ID从内容提供器中获取笔记的摘要信息
mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId);
// 如果获取到的摘要信息长度大于设定的最大长度SNIPPET_PREW_MAX_LEN
mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN? mSnippet.substring(0,
SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info)
: mSnippet;
// 则进行截断处理截取前60个字符并添加一个特定的提示字符串从资源文件中获取否则保持原摘要信息不变
} catch (IllegalArgumentException e) {
// 如果在解析笔记ID或者获取摘要信息过程中出现参数异常比如格式不正确等原因打印异常堆栈信息并直接返回不再执行后续操作
e.printStackTrace();
return;
}
// 创建一个MediaPlayer实例用于后续播放提醒声音
mPlayer = new MediaPlayer();
// 通过DataUtils工具类判断该笔记在笔记数据库中是否可见可能涉及是否被删除、是否处于有效状态等条件判断
// 传入笔记ID以及笔记类型这里是普通笔记类型Notes.TYPE_NOTE进行判断
if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) {
// 如果笔记可见即满足有效条件调用showActionDialog方法显示操作对话框供用户进行相应操作
showActionDialog();
// 调用playAlarmSound方法播放提醒声音
playAlarmSound();
} else {
// 如果笔记不可见直接结束当前Activity意味着不需要展示提醒相关的界面了
finish();
}
}
// 私有方法,用于判断屏幕是否处于开启状态
private boolean isScreenOn() {
// 获取系统的电源管理服务对象,用于查询屏幕的电源状态等信息
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
// 调用电源管理服务对象的isScreenOn方法返回屏幕是否开启的布尔值结果
return pm.isScreenOn();
}
// 私有方法,用于播放提醒声音,比如播放闹钟铃声等
private void playAlarmSound() {
// 通过RingtoneManager获取系统默认的闹钟铃声的Uri用于指定MediaPlayer要播放的音频资源
Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
// 从系统设置中获取静音模式影响的音频流相关设置值,用于判断在静音模式下闹钟声音的播放情况
int silentModeStreams = Settings.System.getInt(getContentResolver(),
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
// 判断静音模式设置中是否影响闹钟音频流如果影响对应位的值不为0
if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM))!= 0) {
// 设置MediaPlayer的音频流类型为获取到的静音模式设置值按照系统静音模式的相关配置来播放声音
mPlayer.setAudioStreamType(silentModeStreams);
} else {
// 如果静音模式不影响闹钟音频流,设置为正常的闹钟音频流类型,确保闹钟声音正常播放
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) {
// 如果在设置数据源等过程中出现参数异常(比如参数不合法等原因),打印异常堆栈信息
e.printStackTrace();
} catch (SecurityException e) {
// 如果出现安全相关异常(比如没有权限访问音频资源等原因),打印异常堆栈信息
e.printStackTrace();
} catch (IllegalStateException e) {
// 如果MediaPlayer的状态出现异常比如在不恰当的状态下执行了某些操作等原因打印异常堆栈信息
e.printStackTrace();
} catch (IOException e) {
// 如果在读取数据源等IO操作过程中出现异常比如音频文件损坏、无法读取等原因打印异常堆栈信息
e.printStackTrace();
}
}
// 私有方法,用于创建并显示操作对话框,给用户提供相应的操作选项,比如确认、进入编辑等操作
private void showActionDialog() {
// 创建一个AlertDialog的构建器对象用于方便地构建AlertDialog对话框
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
// 设置对话框的标题这里使用了字符串资源中的应用名称R.string.app_name对应的字符串作为标题
dialog.setTitle(R.string.app_name);
// 设置对话框的消息内容,展示之前获取到的笔记摘要信息,让用户了解是哪个笔记的提醒
dialog.setMessage(mSnippet);
// 设置对话框的确定按钮通常是一个积极的操作按钮文本以及点击监听器点击监听器使用当前类实现的OnClickListener接口
// 意味着点击该按钮会触发当前类中对应的onClick方法
dialog.setPositiveButton(R.string.notealert_ok, this);
// 如果屏幕处于开启状态设置对话框的另一个按钮可能是进入编辑等操作按钮文本以及点击监听器同样使用当前类实现的OnClickListener接口
if (isScreenOn()) {
dialog.setNegativeButton(R.string.notealert_enter, this);
}
// 构建并显示对话框同时设置对话框的关闭监听器使用当前类实现的OnDismissListener接口
// 意味着对话框关闭时会触发当前类中对应的onDismiss方法
dialog.show().setOnDismissListener(this);
}
// 实现OnClickListener接口的方法用于处理对话框按钮的点击事件根据点击的按钮不同执行相应的逻辑
public void onClick(DialogInterface dialog, int which) {
switch (which) {
// 如果点击的是对话框中的否定按钮(具体含义根据设置的文本而定,这里可能是进入编辑按钮等情况)
case DialogInterface.BUTTON_NEGATIVE:
// 创建一个Intent用于启动NoteEditActivity可能是进入对应的笔记编辑界面方便用户对笔记进行编辑等操作
Intent intent = new Intent(this, NoteEditActivity.class);
// 设置Intent的动作这里设置为查看ACTION_VIEW动作表明是查看相关的操作意图
intent.setAction(Intent.ACTION_VIEW);
// 通过Intent的额外数据传递机制将笔记的ID传递给目标ActivityNoteEditActivity以便目标Activity能获取并处理对应的笔记
intent.putExtra(Intent.EXTRA_UID, mNoteId);
// 启动目标Activity跳转到对应的笔记编辑界面
startActivity(intent);
break;
default:
break;
}
}
// 实现OnDismissListener接口的方法当对话框关闭时会被调用用于执行对话框关闭后的相关操作
public void onDismiss(DialogInterface dialog) {
// 调用stopAlarmSound方法停止播放提醒声音并释放相关的资源如MediaPlayer占用的内存等
stopAlarmSound();
// 结束当前Activity关闭提醒相关的界面完成整个提醒流程
finish();
}
// 私有方法用于停止播放提醒声音并释放MediaPlayer资源将其置为null避免后续出现问题
private void stopAlarmSound() {
if (mPlayer!= null) {
// 停止MediaPlayer的播放如果正在播放声音则立即停止
mPlayer.stop();
// 释放MediaPlayer占用的资源使其回到初始未使用状态
mPlayer.release();
// 将mPlayer对象置为null防止后续误操作该对象同时也符合资源释放后的正确使用习惯
mPlayer = null;
}
}
}