From 9164a4c1b8e2840f5f040fb267f802f9de6bc377 Mon Sep 17 00:00:00 2001 From: jwj <1010652965@qq.com> Date: Wed, 20 Dec 2023 01:15:32 +0800 Subject: [PATCH] =?UTF-8?q?AlarmAlertActivity=E6=A0=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AlarmAlertActivity.java | 202 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 AlarmAlertActivity.java diff --git a/AlarmAlertActivity.java b/AlarmAlertActivity.java new file mode 100644 index 0000000..7225ecb --- /dev/null +++ b/AlarmAlertActivity.java @@ -0,0 +1,202 @@ +/* + * 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; + } + } +} -- 2.34.1