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.
minoteGPZ/AlarmAlertActivity.java

203 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.
*/
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; //文本在数据库存储中的ID号
private String mSnippet; //闹钟提示时出现的文本片段
private static final int SNIPPET_PREW_MAX_LEN = 60;
MediaPlayer mPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
//这一行代码是Activity的onCreate方法声明这是一个受保护的方法当Activity被创建的时候此方法会被调用
//其中Bundle类型的变量savedInstanceState用来传递Activity的保存状态信息
super.onCreate(savedInstanceState); //调用父类的onCreate方法传递保存的状态信息。确保Activity的基本初始化得以执行
requestWindowFeature(Window.FEATURE_NO_TITLE); //请求在Activity的窗口上禁用标题
//括号中的Window.FEATURE_NO_TITLE是一个标志设置以后Activity的窗口将不再显示标题栏
final Window win = getWindow(); //获取当前Activity的窗口对象。通过此对象我们可以对窗口进行各种设置和操作
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
//此处表示为Activity的窗口添加了一个标志。括号中为标志的内容表示即使设备锁屏该Activity窗口
//仍然可以显示内容。这样用户就可以在锁屏的情况下看到Activity的内容
/*
下面这段代码首先通过if语句判断屏幕是否处于开启状态开启则返回false
处于关闭状态则会为Activity的窗口设置一系列的标志
*/
if (!isScreenOn()) {
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON //保持窗体点亮
//这个标志意味着屏幕在Activity可见时保持点亮即使无用户交互的情况下也不会关闭
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON //将窗体点亮
//这个标志表示会在Activity需要显示时打开屏幕
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON //允许窗体点亮时锁屏
//这个标志表示允许屏幕在亮起的状态下进行锁定,即无操作时自动锁屏
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); //手机锁屏后如果到了闹钟提示时间则点亮屏幕
} //这个标志表示允许Activity的窗口在锁屏后仍然可以显示某些内容(如闹钟)
Intent intent = getIntent(); //getIntent()是Android中Activity类的一个方法返回启动的Activity的intent对象
//这行代码即获取启动的Activity的intent对象
/*
*下面这段代码首先尝试从启动的该Activity的intent对象中获取数据并从中提取出mNoteId。它假定intent的数据中包含了一个路径段
并且这个路径段的第二个部分是一个长整型的值。
*接着它使用这个mNoteId从内容解析器getContentResolver()中获取一个与该ID关联的数据片段可能是一个文本或其他数据
*然后代码检查这个数据片段的长度是否超过了预定义的最大长度SNIPPET_PREW_MAX_LEN。如果超过了最大长度
它会截取数据片段的前部分内容,并添加一个字符串资源(可能是一个提示或说明),以确保内容不会超过最大长度。
*如果在上述过程中出现了任何非法参数异常IllegalArgumentException代码会捕获这个异常打印堆栈跟踪并结束执行该方法。
*/
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;
}
/*
下面这段代码的功能是根据某个数据ID是否在数据库中可见来决定执行不同的动作
如果可见则显示一个对话框并播放闹钟提示音如果不可见则结束当前Activity
*/
//MediaPlayer是Android中用于播放音频和视频的一个类
mPlayer = new MediaPlayer(); //创建一个新的MediaPlayer对象实例并将其赋值给变量mPlayer
//这里调用了DataUtils.visibleInNoteDatabase()方法会返回一个布尔值表示给定的ID是否在笔记数据库中可见
if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) {
//getContentResolver()是Android的一个方法获取当前Activity的内容解析器用于访问数据
showActionDialog();//弹出对话框
playAlarmSound(); //闹钟提示音激发
} else {
finish(); //完成闹钟动作
}
}
/*
判断是否锁屏调用系统函数isScreenOn()来判断,返回值为布尔类型
*/
private boolean isScreenOn() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
//getSystemService()是Context类的一个方法它返回一个特定服务的实例这里我们获取的是电源管理服务
return pm.isScreenOn();
}
/*
闹钟的提示音激发
*/
private void playAlarmSound() {
Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
//调用系统的铃声管理URI得到闹钟提示音
int silentModeStreams = Settings.System.getInt(getContentResolver(),
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
//这两行代码从系统设置中获取静音模式影响的音频流
// Settings.System.MODE_RINGER_STREAMS_AFFECTED是一个系统设置指示哪些音频流受到静音模式的影响
/*
检查闹钟的音频流是否受到了静音模式的影响,有,设置音频流为静音;无,设置音频流为闹钟铃声
*/
if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) {
mPlayer.setAudioStreamType(silentModeStreams);
} else {
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
}
try {
mPlayer.setDataSource(this, url); //设置音频的数据源为闹钟铃声的URI
mPlayer.prepare(); //调用prepare方法准备播放器使其处于可以播放的状态
mPlayer.setLooping(true); //设置音频为循环播放
mPlayer.start(); //开始播放音频
/*
在方法的主体中使用了try-catch块来捕获可能出现的异常
如非法参数、安全异常、非法状态和IO异常。这些异常可能在调用播放器方法时抛出
*/
} 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) { //IO异常
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void showActionDialog() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
//用AlertDialog.Builder中的create()方法新建了一个AlertDialog对象
dialog.setTitle(R.string.app_name); //为对话框设置标题
dialog.setMessage(mSnippet); //为对话框设置内容
dialog.setPositiveButton(R.string.notealert_ok, this); //给对话框添加"确定(Positive)"按钮
if (isScreenOn()) {
dialog.setNegativeButton(R.string.notealert_enter, this);
} //给对话框添加"取消(Negative)"按钮
dialog.show().setOnDismissListener(this); //设置对话框消失时的监听器为this
} //点击按钮时会调用下面的OnClick方法
/*
下面这段代码在用户点击取消按钮时启动一个新的 Activity并把当前的 ID 作为额外的数据传递给新的 Activity
*/
public void onClick(DialogInterface dialog, int which) {
switch (which) { //用which来选择click后的下一步操作
case DialogInterface.BUTTON_NEGATIVE: //取消按钮被点击
Intent intent = new Intent(this, NoteEditActivity.class);
//创建一个新的intent对象
intent.setAction(Intent.ACTION_VIEW); //设置动作属性为查看
intent.putExtra(Intent.EXTRA_UID, mNoteId);
//向intent中添加一个数据Intent.EXTRA_UID为键mNoteId为值
startActivity(intent); //启动新的Activity
break;
default:
break;
}
}
public void onDismiss(DialogInterface dialog) {
stopAlarmSound(); //停止闹钟的声音
finish();
}
private void stopAlarmSound() {
if (mPlayer != null) {
mPlayer.stop(); //停止播放
mPlayer.release(); //释放MediaPlayer对象
mPlayer = null;
}
}
}