Android各版本AlarmManager使用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android各版本AlarmManager使用相关的知识,希望对你有一定的参考价值。
参考技术ATimer ,有一个明显的问题,它并不太适合用于需要长期在后台运行的定时任务。我们都知道,为了能让电池更加耐用,每种手机都会有自己的休眠策略,android手机就会在长时间不操作的情况下自动让CPU进入睡眠状态,这就有可能导致Timer中的定时任务无法正常运行。
Hnadler ,Handler的postDelay方法也可以实现定时操作,它同样也是不靠谱的,因为默认Hnadler依赖于线程(main线程或者子线程),所以只要进程被杀死,所有相关的线程都被晒死,所以handler中的定时操作就无效了。Timer也一样,因为Timer实际上是另起一个子线程,进程被杀,子线程当然也被杀了。
AlarmManager ,它通过pendingIntent具有唤醒未启动进程的功能,即可以保证每次需要执行定时任务的时候CPU都能正常工作。但是当设备关机和重启后,闹钟将被清除。
通过上面的分析,我们可以明显感受到AlarmManager在长时间定时任务中的优点,下面来说说它的用法( 由于AlarmManager在不同的Android版本都有修改,所以如果想使用AlarmManager需要处理不同版本问题 )
这个就要区分Android版本了
4.4之前,SDK API < 19
或
4.4之后,6.0之前, SDK API >= 19, SDK API < 23
查阅 Android 官网中关于 Android 4.4 API 会看到如下几句话:
6.0之后的版本,SDK API >= 23
再次打开 Android 官网中关于 Android 6.0 变更 ,发现在 Android 6.0 中引入了低电耗模式和应用待机模式。然后接着往下看 对低电耗模式和应用待机模式进行针对性优化 ,发现会有下面一段话:
Android中AlarmManager使用示例(持续更新)
现在普遍的手机都会有一个闹钟的功能,如果使用Android来实现一个闹钟可以使用AtarmManager来实现。AtarmManager提供了一种系统级的提示服务,允许你安排在将来的某个时间执行一个服务。AlarmManager对象一般不直接实例化,而是通过Context.getsystemservice(Context.ALARM_SERVICE)方法获得。
下面是我们运用之前用到的TimePickerDialog结合AlarmManager,实现一个可以设定任意时间而且可以重复的闹钟,演示效果如下(大概每晚23:48会有闹钟通知):
layout中activity_main.xml布局文件代码:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:id="@+id/activity_main" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 android:orientation="vertical" 9 tools:context="com.example.administrator.alarmdemo.MainActivity"> 10 <TextView 11 android:id="@+id/time_tv" 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:hint="请设置闹铃时间" 15 android:clickable="true" 16 android:onClick="setTime" 17 android:gravity="center"/> 18 <TextView 19 android:id="@+id/time_tv2" 20 android:layout_width="match_parent" 21 android:layout_height="wrap_content" 22 android:hint="请设置响铃间隔时间" 23 android:clickable="true" 24 android:onClick="setIntervalTime" 25 android:gravity="center"/> 26 <Button 27 android:layout_width="match_parent" 28 android:layout_height="wrap_content" 29 android:onClick="open" 30 android:text="开启闹钟"/> 31 <Button 32 android:layout_width="match_parent" 33 android:layout_height="wrap_content" 34 android:onClick="stop" 35 android:text="结束闹钟"/> 36 </LinearLayout>
AndroidMainfest.xml配置文件(添加自定义重复闹铃receiver):
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.administrator.alarmdemo"> 4 <application 5 android:allowBackup="true" 6 android:icon="@mipmap/ic_launcher" 7 android:label="@string/app_name" 8 android:supportsRtl="true" 9 android:theme="@style/AppTheme"> 10 <activity android:name=".MainActivity"> 11 <intent-filter> 12 <action android:name="android.intent.action.MAIN" /> 13 14 <category android:name="android.intent.category.LAUNCHER" /> 15 </intent-filter> 16 </activity> 17 <receiver 18 android:name=".RepeatAlarmReceiver" 19 android:enabled="true" 20 android:exported="true"> 21 <intent-filter> 22 <action android:name="repeatAlarm" /> 23 </intent-filter> 24 </receiver> 25 <activity android:name=".Main2Activity"></activity> 26 </application> 27 28 </manifest>
RepeatAlarmReceiver.java广播接收文件:
1 import android.content.BroadcastReceiver; 2 import android.content.Context; 3 import android.content.Intent; 4 import android.widget.Toast; 5 6 public class RepeatAlarmReceiver extends BroadcastReceiver { 7 public RepeatAlarmReceiver() { 8 } 9 @Override 10 public void onReceive(Context context, Intent intent) { 11 Toast.makeText(context, "重复闹钟", Toast.LENGTH_SHORT).show(); 12 } 13 }
MainActivity.java代码实现:
1 import android.app.AlarmManager; 2 import android.app.PendingIntent; 3 import android.app.TimePickerDialog; 4 import android.content.Intent; 5 import android.provider.Settings; 6 import android.support.v7.app.AppCompatActivity; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.widget.TextView; 10 import android.widget.TimePicker; 11 import java.util.Calendar; 12 public class MainActivity extends AppCompatActivity { 13 AlarmManager alarmManagerSet; 14 PendingIntent pendingIntentSet; 15 int myHour,myMinute;//声明响铃时间 16 int intervalHour,intervalMinute,intervalSecond;//声明间隔时间(响铃周期) 17 Calendar calendar;//声明日历 18 TextView time_tv,time_tv2; 19 20 @Override 21 protected void onCreate(Bundle savedInstanceState) { 22 super.onCreate(savedInstanceState); 23 setContentView(R.layout.activity_main); 24 alarmManagerSet= (AlarmManager) getSystemService(ALARM_SERVICE); 25 //设置声明时间格式 26 calendar = Calendar.getInstance(); 27 myHour=calendar.get(Calendar.HOUR_OF_DAY); 28 myMinute=calendar.get(Calendar.MINUTE); 29 intervalHour=calendar.get(Calendar.HOUR_OF_DAY); 30 intervalMinute=calendar.get(Calendar.MINUTE); 31 //获取时间设置的TextView 32 time_tv= (TextView) findViewById(R.id.time_tv); 33 time_tv2= (TextView) findViewById(R.id.time_tv2); 34 } 35 //使用timePickerDialog设置闹铃响铃时间 36 public void setTime(View view){ 37 TimePickerDialog timePickerDialog =new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() { 38 @Override 39 public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 40 myHour=hourOfDay; 41 myMinute=minute; 42 time_tv.setText(myHour+":"+myMinute); 43 } 44 },myHour,myMinute,true); 45 timePickerDialog.show(); 46 } 47 //使用timePickerDialog设置闹铃响铃周期(间隔) 48 public void setIntervalTime(View view){ 49 TimePickerDialog timePickerDialog =new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() { 50 @Override 51 public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 52 intervalHour=hourOfDay; 53 intervalMinute=minute; 54 time_tv2.setText(intervalHour+":"+intervalMinute); 55 } 56 },intervalHour,intervalMinute,true); 57 timePickerDialog.show(); 58 } 59 public void open(View view){ 60 //分别获取闹铃响铃时间以及闹铃间隔时间(用冒号分割存储于数组中) 61 String[] triggerTime=time_tv.getText().toString().split(":"); 62 String[] intervalTime=time_tv2.getText().toString().split(":"); 63 //通过Calendar分别获取对应的小时和分钟(需要将String转换为int) 64 Calendar calendar1 = Calendar.getInstance(); 65 calendar1.set(Calendar.HOUR_OF_DAY,Integer.parseInt(triggerTime[0])); 66 calendar1.set(Calendar.MINUTE,Integer.parseInt(triggerTime[1])); 67 //得到点击触发的毫秒值(即闹钟提醒时间) 68 long triggerAtMillis= calendar1.getTimeInMillis(); 69 //设定pendinngIntent接受自定义闹铃广播 70 pendingIntentSet = PendingIntent.getBroadcast(this,0,new Intent("repeatAlarm"),0); 71 //判断如果当前系统时间大于设置的闹铃时间,则在第二天开始启用该闹铃 72 if(System.currentTimeMillis()>triggerAtMillis){ 73 triggerAtMillis=triggerAtMillis+24*60*60*1000; 74 } 75 //使用.setRepeating设置重复闹铃 76 alarmManagerSet.setRepeating(AlarmManager.RTC_WAKEUP,triggerAtMillis,intervalMillis,pendingIntentSet); 77 } 78 public void stop(View v){ 79 alarmManagerSet.cancel(pendingIntentSet); 80 } 81 }
以上是关于Android各版本AlarmManager使用的主要内容,如果未能解决你的问题,请参考以下文章
android app被杀死 alarmmanager能不能唤醒
android 使用timertask和alarmmanager哪个好点