关于android中alarm的使用

本文详细介绍了如何在Android应用中实现闹钟功能。通过使用AlarmManager设置重复的提醒任务,并创建BroadcastReceiver来处理闹钟触发时的动作。文章还强调了在Android 4.4及以后版本中闹钟唤醒时间可能存在的不准确性。
**最近项目中需要完成一个需求:实现类似于闹钟的功能,能够在指定的时间唤醒。
于是开始使用alarmManager。。。。查了查别人的博客之后
开始的代码是这么写的:**
private void setTime() {
        // 当前设备上的系统时间
        final Calendar cal = Calendar.getInstance();
        // 弹出设置时间的窗口
        new TimePickerDialog(this, new OnTimeSetListener() {

            @Override
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                Intent intent = new Intent(context, AlarmNotifyAcitivity.class);
                PendingIntent pi = PendingIntent.getActivity(context, 0,
                        intent, 0);
                Calendar setCalendar = Calendar.getInstance();
                setCalendar.set(Calendar.HOUR, hourOfDay);
                setCalendar.set(Calendar.MINUTE, minute);
                AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
                manager.setRepeating(AlarmManager.RTC_WAKEUP,
                        setCalendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pi);
                timeSetBtn.setText(setCalendar.get(Calendar.HOUR) + ":"
                        + setCalendar.get(Calendar.MINUTE));
                Toast.makeText(context, "闹铃设置成功", Toast.LENGTH_SHORT).show();
            }
        }, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), true)
                .show();
    }

intent中指定的activity用来处理逻辑
但是现实是–根本没有任何的反应!!
查了查官方的api发现,android在alarm设定之后,启动时发送的是广播,使用getActivity得到的pendingintent是无法实现效果的,并且需要一个继承自广播接收器的类接收广播,于是更改代码:

private void setTime() {
        // 当前设备上的系统时间
        final Calendar cal = Calendar.getInstance();
        // 弹出设置时间的窗口
        new TimePickerDialog(this, new OnTimeSetListener() {

            @Override
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                Intent intent = new Intent(context, AlarmNotifyReceiver.class);
                PendingIntent pi = PendingIntent.getBroadcast(context, 0,
                        intent, 0);
                Calendar setCalendar = Calendar.getInstance();
                setCalendar.set(Calendar.HOUR, hourOfDay);
                setCalendar.set(Calendar.MINUTE, minute);
                AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
                manager.setRepeating(AlarmManager.RTC_WAKEUP,
                        setCalendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pi);
                timeSetBtn.setText(setCalendar.get(Calendar.HOUR) + ":"
                        + setCalendar.get(Calendar.MINUTE));
                Toast.makeText(context, "闹铃设置成功", Toast.LENGTH_SHORT).show();
            }
        }, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), true)
                .show();
    }

用来接收广播的类:

public class AlarmNotifyReceiver extends BroadcastReceiver {

    private MediaPlayer notice;

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "启动闹钟", Toast.LENGTH_SHORT).show();
        notice = MediaPlayer.create(context,
                RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM));
        notice.setLooping(true);
        try {
            notice.prepare();
            notice.start();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("日常提醒闹钟").setMessage("请执行操作")
                .setPositiveButton("好哒~~", new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        notice.stop();
                    }
                });
        AlertDialog dialog=builder.create();
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        dialog.show();
    }
}

这里我做的是显示一个alert,注意如果不设置settype再运行时会报错!!!注意如果不设置settype再运行时会报错!!!注意如果不设置settype再运行时会报错!!!重要的事情说三遍。。。
但是设置之后运行,依然还是报错:-。-
需要注册权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
ok,大功告成!!
但是有点需要特别提醒,android自从4.4之后,唤醒的时间未必是完全准确的,系统会将某一段时间内需要唤醒的放在一个时间唤醒,而这个时间未必是你设定的时间。

### AlarmManager 使用教程 #### 一、AlarmManager 概述 在Android应用开发中,定时任务的需求十分常见,例如周期性执行特定操作、提醒用户或是同步数据等。为了满足这些需求,Android 提供了多种实现方案,而 `AlarmManager` 则以其灵活性强大功能脱颖而出[^1]。 #### 二、AlarmManager 基本概念与工作原理 作为Android平台下的重要系统服务之一,`AlarmManager` 主要负责设定一次性或重复性的定时任务。该组件能够使应用程序即使处于后台运行状态也能按照预定的时间触发相应的事件处理逻辑。值得注意的是,在不同版本的Android操作系统上,由于电源管理模式(如Doze模式)的影响,`AlarmManager` 的行为可能会有所差异[^2]。 #### 三、获取AlarmManager 实例的方法 通常情况下,不会直接创建 `AlarmManager` 对象实例,而是借助于 `Context.getSystemService()` 方法来获取其引用: ```java AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); ``` 这段代码展示了如何从当前上下文中取得 `AlarmManager` 服务对象[^3]。 #### 四、设置并取消报警器 下面给出一段简单的Java代码片段,用于说明怎样配置一个广播接收者以响应由 `AlarmManager` 发起的通知;同时也演示了如何取消已注册的任务。 ```java // 创建意图并与广播接收者关联 Intent intent = new Intent(this, MyBroadcastReceiver.class); // 获取PendingIntent对象 PendingIntent pendingIntent = PendingIntent.getBroadcast( this, REQUEST_CODE, intent, flags // 可能需要根据API级别调整flags参数 ); // 设置单次警报 am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerTimeMillis, pendingIntent); // 若要取消上述设置,则调用如下语句 am.cancel(pendingIntent); ``` 这里需要注意的是,在较新的Android API等级下可能需要用到不同的标志位组合来确保兼容性准确性[^4]。 #### 五、定义广播接收者的具体行为 最后一步是要编写自定义类继承自 `BroadcastReceiver` ,重写 `onReceive()` 方法从而定义当接收到通知时应采取的动作。以下是一个简单例子: ```java public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 执行所需的操作... Toast.makeText(context, "闹钟响啦!", Toast.LENGTH_LONG).show(); } } ``` 此部分实现了每当指定时刻到来之际向用户显示一条短暂的消息框[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值