AlarmManager (alarm clock service)
Introduction to this section:
This section introduces the AlarmManager (alarm clock service) in Android. From the name, we know that we can use it to develop mobile alarm clock APPs. The explanation in the document is: broadcast a specified Intent for us at a specific moment. Simply put, we set a time ourselves. Then when the time is up, the AlarmManager will broadcast an Intent we set for us. For example, when the time is up, it can point to a certain Activity or Service! In addition, there are some things to pay attention to in the official documents:
Another thing to note is that AlarmManager is mainly used to run your code at a certain moment, even if your APP is that specific Time is not running! Also, starting from API 19, the Alarm mechanism is not passed accurately, and the operating system will convert the alarm clock , to minimize wake-ups and battery usage! Some new APIs will support strictly accurate delivery, see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). TargetSdkVersion applications prior to API 19 will continue to use the previous behavior, and all alarms will be delivered accurately when required It will be delivered accurately next time. For more details, please see the official API document: AlarmManager
##1. The difference between the Timer class and the AlarmManager class:
If you have learned J2SE, then you will definitely be familiar with Timer. Timer is usually used when writing scheduled tasks. It is definitely inseparable from him, but in Android, he has a shortcoming and is not suitable for those that need to run in the background for a long time. Scheduled tasks, because Android devices have their own sleep policies. When there is no operation for a long time, the device will automatically let the CPU enter Sleep state, which may cause the scheduled tasks in Timer to not run properly! And AlarmManager does not exist In this case, because it has the function of waking up the CPU, it can ensure that the CPU can work normally every time it needs to perform a specific task. In other words, the alarm clock registered when the CPU is sleeping will be retained (can wake up the CPU), but if the device is turned off or restarted, If activated, the alarm will be cleared! (The alarm clock does not sound when the Android phone is turned off...)
2. Obtain the AlarmManager instance object:
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
3. Explanation of related methods:
- set(int type, long startTime, PendingIntent pi): One-time alarm
- setRepeating(int type, long startTime, long intervalTime, PendingIntent pi): Repeating alarm clock, which is different from 3, 3 alarm clock interval is not fixed
- setInexactRepeating (int type, long startTime, long intervalTime, PendingIntent pi): Repetitive alarm clock, time is not fixed
- cancel(PendingIntent pi): Cancel the scheduled service of AlarmManager
- getNextAlarmClock(): Get the next alarm clock , return value AlarmManager.AlarmClockInfo
- setAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) Similar to the set method, this alarm clock is valid when the system is in low power mode
- setExact(int type, long triggerAtMillis, PendingIntent operation): Execute the alarm clock accurately at the specified time, which is more accurate than the set method.
- setTime(long millis): Set the time on the system wall
- setTimeZone(String timeZone): Set the system's persistent default time zone
- setWindow(int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation): Set an alarm to fire within a given time window. Similar to set, this method allows applications to precisely control operating system adjustments. The extent of the entire alarm trigger time.
Explanation of key parameters:
- Type(Alarm clock type): There are five optional values: AlarmManager.ELAPSED_REALTIME: The alarm clock is not available when the phone is in sleep state. In this state, the alarm clock uses relative time (relative to the start of system startup), and the state value is 3; AlarmManager.ELAPSED_REALTIME_WAKEUPThe alarm clock will wake up the system and perform prompt functions in the sleep state. In this state, the alarm clock also uses relative time, and the status value is 2; AlarmManager.RTCThe alarm clock is not available in the sleep state. In this state, the alarm clock uses absolute time, that is, the current system time, and the status value is 1; AlarmManager.RTC_WAKEUP means that the alarm clock will wake up the system and perform prompt functions in the sleep state. In this state, the alarm clock uses absolute time and the status value is 0; AlarmManager.POWER_OFF_WAKEUP means that the alarm clock can also perform the prompt function normally when the phone is turned off, so it is one of the most commonly used states among the 5 states. In this state, the alarm clock also uses absolute time, and the state value is 4 ; However, this status seems to be affected by the SDK version, and some versions do not support it;
- startTime: The first execution time of the alarm clock, in milliseconds, the time can be customized, but Generally use the current time. It should be noted that this attribute is closely related to the first attribute (type). If the alarm clock corresponding to the first parameter uses relative time (ELAPSED_REALTIME and ELAPSED_REALTIME_WAKEUP), then this attribute must use relative time (relative to system startup time), for example, the current time is expressed as: SystemClock.elapsedRealtime(); If the alarm clock corresponding to the first parameter uses absolute time (RTC, RTC_WAKEUP, POWER_OFF_WAKEUP), Then this attribute must use absolute time. For example, the current time is expressed as: System.currentTimeMillis().
- intervalTime: Indicates the interval between two alarm executions, also in milliseconds.
- PendingIntent: Binds the execution action of the alarm clock , such as sending a broadcast, giving prompts, etc. PendingIntent is the encapsulation class of Intent. It should be noted that if the alarm prompt is implemented by starting a service, the PendingIntent object should be obtained using Pending.getService (Context c, int i, Intent intent, int j) method; if the alarm clock is implemented through broadcasting As a reminder, PendingIntent.getBroadcast should be used to obtain the PendingIntent object. (Context c, int i, Intent intent, int j) method; if it is implemented using Activity If the alarm clock prompts, the PendingIntent object should be obtained using PendingIntent.getActivity(Context c,int i,Intent intent,int j) method. If these three methods are used incorrectly, although no error will be reported, the alarm prompt effect will not be visible.
4. Usage example: a simple scheduled task
What I want to say is that this example is only feasible in systems below Android 4.4. Above 5.0 is not feasible, if there is 5.0 in the future The above AlarmManager solution will be added in due course! In addition, using the set method here may be a bit inaccurate. If you want To be more precise, you can use the setExtra() method to set the AlarmManager!
Running renderings:
Implementation code:
First a simple layout file:activity_main.xml, and create a raw folder in res and throw the audio file into it! In addition, create an activity_clock.xml with only the outer layout as the layout of the Activity when the alarm clock sounds! If there is nothing, I won’t post it
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btn_set" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="设置闹钟" /> <Button android:id="@+id/btn_cancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="关闭闹钟" android:visibility="gone" /></LinearLayout>
followed by MainActivity.java, which is also very simple:
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 alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi); Log.e("HEHE",c.getTimeInMillis()+""); //这里的时间是一个unix时间戳 // 提示闹钟设置完毕: Toast.makeText(MainActivity.this, "闹钟设置完毕~"+ c.getTimeInMillis(), 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; } } }
Then the ClockActivity.java# of the alarm page ##:
/** * Created by Jay on 2015/10/25 0025. */ 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.pig); 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(); } }The code is very simple, the core process is as follows:
In addition, if the alarm is invalid, you can start from these aspects:AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
- Get the AlarmManager service provided by the system The object
- Intent sets the component to be launched: Intent intent = new Intent(MainActivity.this, ClockActivity.class);
- The PendingIntent object sets the action, whether it is an Activity, a Service, or a broadcast!PendingIntent pi = PendingIntent.getActivity (MainActivity.this, 0, intent, 0);
- Call the set() method of AlarmManager to set the alarm type, startup time and PendingIntent object of a single alarm!alarmManager.set(AlarmManager .RTC_WAKEUP,c.getTimeInMillis(), pi);
- System version or mobile phone, above 5.0 is basically useless, Xiaomi, go to Baidu by yourself~ 2.Has ClockActivity been registered? 3. If you are using alarmManager to send broadcasts, and then activate the Activity after broadcasting, you need to set a flag for the Intent: i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- 4.
- ##These places are written correctly~Don’t write getActivity as getService, etc.~
4.2.2 Service Advanced
##In addition, about AlarmManager combined with later Service For examples of implementing scheduled background tasks, see:
AlarmManagerDemo.zip
Summary of this section:
Okay, this section explains to you the use of AlarmManager (alarm clock service) in Android. In addition to being able to customize it like the example An alarm clock of your own can also be combined with Service and Thread to complete polling, etc. There are many ways to use it, and you still need to explore by yourself, eh That’s it for this section, thank you~