Android AlarmManager 闹钟服务 |
您所在的位置:网站首页 › 表演的闹钟 › Android AlarmManager 闹钟服务 |
闹钟服务( AlarmManager) 会在在特定的时刻为我们广播一个指定的 Intent,简单说就是我们自己定一个时间,然后当到时间时,AlarmManager 会为我们广播一个我们设定好的 Intent AlarmManager 主要是用来在某个时刻运行某些的代码的,即使 APP 在那个特定时间并没有运行 从 API 19 开始,Alarm 的机制都是非准确传递的,操作系统将会转换闹钟,来最小化唤醒和电池的使用,但某些新的 API 会支持严格准确的传递,比如 setWindow(int, long, long, PendingIntent) setExact(int, long, PendingIntent)targetSdkVersion 在 API 19 之前应用仍将继续使用以前的行为,所有的闹钟在要求准确传递的情况下都会准确传递 AlarmManagerAndroid 设备有自己的休眠策略,当长时间的无操作,设备会自动让 CPU 进入休眠状态 AlarmManager 则具有唤醒 CPU 的功能,可以保证每次需要执行特定任务时 CPU 都能正常工作, 或者说当 CPU 处于休眠时注册的闹钟会被保留(可以唤醒 CPU),但如果设备被关闭,或者重新 启动的话,闹钟将被清除 获得 AlarmManager 实例对象 AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); AlarmManager 方法列表 方法 说明 set(int type,long startTime,PendingIntent pi) 一次性闹钟 setRepeating(int type,long startTime,long intervalTime,PendingIntent pi) 重复性闹钟,和 3 有区别,3 闹钟间隔时间不固定 setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi 重复性闹钟,时间不固定 cancel(PendingIntent pi) 取消 AlarmManager 的定时服务 getNextAlarmClock() 得到下一个闹钟,返回值AlarmManager.AlarmClockInfo setAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) 和 set 方法类似,这个闹钟运行在系统处于低电模式时有效 setExact(int type, long triggerAtMillis, PendingIntent operation) 在规定的时间精确的执行闹钟,比set方法设置的精度更高 setTime(long millis) 设置系统墙上的时间 setTimeZone(String timeZone) 设置系统持续的默认时区 setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation) 设置一个闹钟在给定的时间窗触发。类似于set,该方法允许应用程序精确地控制操作系统调整闹钟触发时间的程度 关键参数解析type 闹钟类型,有五个可选值 值 说明 AlarmManager.ELAPSED_REALTIME 闹钟在手机睡眠状态下不可用,该状态下闹钟使用相对时间(相对于系统启动开始),状态值为3; AlarmManager.ELAPSED_REALTIME_WAKEUP 闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟也使用相对时间,状态值为2; AlarmManager.RTC 闹钟在睡眠状态下不可用,该状态下闹钟使用绝对时间,即当前系统时间,状态值为1; AlarmManager.RTC_WAKEUP 表示闹钟在睡眠状态下会唤醒系统并执行提示功能,该状态下闹钟使用绝对时间,状态值为0; AlarmManager.POWER_OFF_WAKEUP 表示闹钟在手机关机状态下也能正常进行提示功能,所以是5个状态中用的最多的状态之一,该状态下闹钟也是用绝对时间,状态值为4;不过本状态好像受SDK版本影响,某些版本并不支持;startTime 闹钟的第一次执行时间,以毫秒为单位,可以自定义时间,不过一般使用当前时间 需要注意的是,该属性与 type 属性密切相关 如果第一个参数对应的闹钟使用的是相对时间(ELAPSED_REALTIME 和 ELAPSED_REALTIME_WAKEUP),那么本属性就得使用相对时间(相对于系统启动时间来说),比如当前时间就表示为:SystemClock.elapsedRealtime(); 如果第一个参数对应的闹钟使用的是绝对时间 (RTC、RTC_WAKEUP、POWER_OFF_WAKEUP),那么本属性就得使用绝对时间,比如当前时间就表示 为:System.currentTimeMillis() intervalTime 表示两次闹钟执行的间隔时间,也是以毫秒为单位 PendingIntent 绑定了闹钟的执行动作,比如发送一个广播、给出提示等等 PendingIntent 是 Intent 的封装类 需要注意的是,如果是通过启动服务来实现闹钟提示的话,PendingIntent 对象的获取就应该采用 Pending.getService (Context c,int i,Intent intent,int j)如果是通过广播来实现闹钟提示的话,PendingIntent 对象的获取就应该采用 PendingIntent.getBroadcast(Context c,int i,Intent intent,int j)如果是采用 Activity 的方式来实现闹钟提示的话,PendingIntent 对象的获取就应该采用 PendingIntent.getActivity(Context c,int i,Intent intent,int j)如果这三种方法错用了的话,虽然不会报错,但是看不到闹钟提示效果 使用 AlarmManager 的一般流程获得系统提供的 AlarmManager 服务的对象 AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);创建 Intent 设置要启动的组件 Intent intent = new Intent(MainActivity.this, ClockActivity.class);PendingIntent 对象设置动作,启动的是 Activity 还是 Service 又或者是广播 PendingIntent pi = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);调用 alarmManager.set() 方法设置单次闹钟的闹钟类型,启动时间以及 PendingIntent 对象 alarmManager.set(AlarmManager.RTC_WAKEUP,c.getTimeInMillis(), pi);如果使用 alarmManager 发送广播,广播再激活 Activity 的话,则需要为 Intent 设置一个 flag i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 一个简单的闹钟使用 set() 方法可能有点不准,如果要更精确的话可以使用 setExtra() 方法来设置 AlarmManager 创建一个 空的 Android 项目 cn.twle.android.Alarm 在 res 目录上点右键,然后选择 Android resource directory,在弹出的界面中 Resource type 项选择 raw 然后点击 OK 下载音频文件 /static/i/android/alarm.mp3 并放到 res/raw 目录下 修改 activity_main.xml 创建闹铃布局 activity_clock.xml 作为闹钟响时 Activity 的布局 创建一个闹铃页面的 ClockActivity.java package cn.twle.android.alarm; import android.app.AlertDialog; import android.content.DialogInterface; import android.media.MediaPlayer; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; public class ClockActivity extends AppCompatActivity { private MediaPlayer mediaPlayer; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_clock); mediaPlayer = mediaPlayer.create(this,R.raw.alarm); mediaPlayer.start(); //创建一个闹钟提醒的对话框,点击确定关闭铃声与页面 new AlertDialog.Builder(ClockActivity.this).setTitle("闹钟").setMessage("小猪小猪快起床~") .setPositiveButton("关闭闹铃", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mediaPlayer.stop(); ClockActivity.this.finish(); } }).show(); } }创建一个广播接收器,接收闹铃服务 MsAlarmReceiver.java package cn.twle.android.alarm; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class MsAlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent i = new Intent(context,ClockActivity.class); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); } }修改 AndroidManifest.xml 添加 Activity 和 MsAlarmReceiver 修改 MainActivity.java package cn.twle.android.alarm; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.TimePickerDialog; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.os.Build; import android.view.View; import android.widget.Button; import android.widget.TimePicker; import android.widget.Toast; import java.util.Calendar; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button btn_set; private Button btn_cancel; private AlarmManager alarmManager; private PendingIntent pi; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindViews(); } private void bindViews() { btn_set = (Button) findViewById(R.id.btn_set); btn_cancel = (Button) findViewById(R.id.btn_cancel); alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); Intent intent = new Intent(MainActivity.this, ClockActivity.class); pi = PendingIntent.getActivity(MainActivity.this, 0, intent, 0); btn_set.setOnClickListener(this); btn_cancel.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_set: Calendar currentTime = Calendar.getInstance(); new TimePickerDialog(MainActivity.this, 0, new TimePickerDialog.OnTimeSetListener() { @Override public void onTimeSet(TimePicker view, int hourOfDay, int minute) { //设置当前时间 Calendar c = Calendar.getInstance(); c.setTimeInMillis(System.currentTimeMillis()); // 根据用户选择的时间来设置Calendar对象 c.set(Calendar.HOUR, hourOfDay); c.set(Calendar.MINUTE, minute); // ②设置AlarmManager在Calendar对应的时间启动Activity if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi); }else { alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi); } // 提示闹钟设置完毕: Toast.makeText(MainActivity.this, "闹钟设置完毕", Toast.LENGTH_SHORT).show(); } }, currentTime.get(Calendar.HOUR_OF_DAY), currentTime .get(Calendar.MINUTE), false).show(); btn_cancel.setVisibility(View.VISIBLE); break; case R.id.btn_cancel: alarmManager.cancel(pi); btn_cancel.setVisibility(View.GONE); Toast.makeText(MainActivity.this, "闹钟已取消", Toast.LENGTH_SHORT) .show(); break; } } }不能用啊,算了,现在没空去想要怎么优化 参考文档 Android 官方 API 文档: AlarmManager |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |