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.
123456/java/net/micode/notes/ui/AlarmAlertActivity.java

192 lines
9.9 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.
* 以下是这段代码中主要的函数及其功能介绍:
onCreate 函数
所属类AlarmAlertActivity
功能:
首先调用父类Activity的 onCreate 方法进行基础的初始化操作。
通过 requestWindowFeature 方法请求去除 Activity 的标题栏(使用 Window.FEATURE_NO_TITLE 特性)。
获取当前窗口对象 win并添加一些窗口相关的标志位例如 FLAG_SHOW_WHEN_LOCKED 让窗口在屏幕锁定时也能显示,还会根据屏幕是否亮起(通过 isScreenOn 函数判断)来添加如 FLAG_KEEP_SCREEN_ON 等其他与屏幕状态控制相关的标志位,用于控制屏幕的显示和锁定等行为。
从传入的 Intent 中获取相关数据,尝试解析出笔记的 IDmNoteId以及对应的简短内容片段mSnippet若解析出现 IllegalArgumentException 异常则打印堆栈信息并返回,不继续后续流程。
创建 MediaPlayer 实例 mPlayer接着判断笔记在数据库中的可见性通过 DataUtils.visibleInNoteDatabase 函数判断),如果可见则调用 showActionDialog 显示操作对话框,并调用 playAlarmSound 播放闹钟声音,若不可见则直接结束当前 Activity。
isScreenOn 函数
所属类AlarmAlertActivity
功能获取系统的电源管理服务PowerManager通过调用其 isScreenOn 方法来判断当前屏幕是否处于亮起状态,返回一个布尔值,用于后续决定添加哪些窗口相关的标志位等操作。
playAlarmSound 函数
所属类AlarmAlertActivity
功能:
首先通过 RingtoneManager.getActualDefaultRingtoneUri 方法获取系统默认闹钟铃声的 Uri 地址。
接着从系统设置中获取静音模式影响的音频流相关设置(通过 Settings.System.getInt 获取 Settings.System.MODE_RINGER_STREAMS_AFFECTED 的值),根据其值来设置 MediaPlayermPlayer的音频流类型若满足特定条件则设置为获取到的 silentModeStreams否则设置为 AudioManager.STREAM_ALARM。
然后尝试设置 MediaPlayer 的数据源(通过 setDataSource 方法传入当前 Activity 上下文和铃声 Uri并进行准备prepare操作设置为循环播放setLooping 为 true最后启动播放start。过程中如果出现如 IllegalArgumentException、SecurityException、IllegalStateException、IOException 等异常会打印相应的堆栈信息。
showActionDialog 函数
所属类AlarmAlertActivity
功能:
创建一个 AlertDialog.Builder 实例用于构建对话框,设置对话框的标题(通过 R.string.app_name 资源字符串获取标题内容)、消息内容(使用之前获取的笔记内容片段 mSnippet
设置对话框的确定按钮(通过 setPositiveButton 方法,按钮文本使用 R.string.notealert_ok 资源字符串,点击事件绑定到当前类实现的 onClick 方法),并且在屏幕亮起的情况下(通过 isScreenOn 函数判断),设置进入按钮(通过 setNegativeButton 方法,按钮文本使用 R.string.notealert_enter 资源字符串,点击事件同样绑定到 onClick 方法)。
最后调用 show 方法显示对话框,并设置对话框关闭的监听器(通过 setOnDismissListener 绑定到当前类实现的 onDismiss 方法)。
onClick 函数
所属类AlarmAlertActivity
功能:实现了 DialogInterface.OnClickListener 接口的方法,根据点击对话框按钮的 which 参数进行不同操作。当点击了对话框的否定(消极)按钮(对应 DialogInterface.BUTTON_NEGATIVE也就是 notealert_enter 按钮)时,创建一个新的 Intent指定目标 Activity 为 NoteEditActivity设置 Intent 的动作ACTION_VIEW以及传递笔记的 ID通过 putExtra 传递 Intent.EXTRA_UID 附加数据),然后启动对应的 Activity用于进入笔记编辑页面等相关操作。对于其他按钮点击情况暂时不做额外处理default 分支)。
onDismiss 函数
所属类AlarmAlertActivity
功能:实现了 DialogInterface.OnDismissListener 接口的方法,当对话框关闭时被调用。在这个函数中,会调用 stopAlarmSound 函数停止正在播放的闹钟声音,然后结束当前 Activity完成整个与闹钟提醒相关的流程清理和关闭操作。
stopAlarmSound 函数
所属类AlarmAlertActivity
功能:用于停止并释放 MediaPlayer 资源。首先判断 mPlayer 是否为 null如果不为 null则调用 stop 方法停止播放,接着调用 release 方法释放相关资源,最后将 mPlayer 置为 null确保资源被正确回收避免内存泄漏等问题。
*/
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;
public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener {
private long mNoteId;
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);
}
Intent intent = getIntent();
try {
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();
}
}
private boolean isScreenOn() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
return pm.isScreenOn();
}
private void playAlarmSound() {
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) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
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);
}
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;
}
}
public void onDismiss(DialogInterface dialog) {
stopAlarmSound();
finish();
}
private void stopAlarmSound() {
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
}
}