首先写几点感悟:
做兼容真的很累很费劲~
android 8.0 广播部分不再支持动态注册,所以应该用service来实现定时推送功能
无论是闹钟还是通知,都得做兼容处理,android 8.0通知必须加channel_id,否则通知无法显示
查阅大量资料,发现代码都参差不齐,不过还是有很多值得参考的地方,目前这份代码有很多都是抄字那些博主的文章,然后稍加改动,加以整合而成
代码分为三个类,service类、闹钟工具类和通知工具类
首先,闹钟工具类:
package com.util;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import java.io.Serializable;
import java.util.Map;
/**
* 闹钟定时工具类
*/
public class AlarmTimerUtil {
/**
* 设置定时闹钟
*
* @param context
* @param alarmId
* @param action
* @param map 要传递的参数
*/
public static void setAlarmTimer(Context context, int alarmId, long time, String action,Map map) {
Intent myIntent = new Intent();
myIntent.setAction(action);
if(map != null){
for (String key: map.keySet()) {
myIntent.putExtra(key,map.get(key));
}
}
// PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, myIntent, 0);//如果是广播,就这么写
PendingIntent sender = PendingIntent.getService(context, alarmId, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //MARSHMALLOW OR ABOVE
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, sender);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //LOLLIPOP 21 OR ABOVE
AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(time, sender);
alarmManager.setAlarmClock(alarmClockInfo, sender);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //KITKAT 19 OR ABOVE
alarmManager.setExact(AlarmManager.RTC_WAKEUP, time, sender);
} else { //FOR BELOW KITKAT ALL DEVICES
alarmManager.set(AlarmManager.RTC_WAKEUP, time, sender);
}
}
/**
* 取消闹钟
* @param context
* @param action
*/
public static void cancelAlarmTimer(Context context, String action,int alarmId) {
Intent myIntent = new Intent();
myIntent.setAction(action);
// PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, myIntent, 0);//如果是广播,就这么写
PendingIntent sender = PendingIntent.getService(context, alarmId, myIntent,0);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(sender);
}
}
闹钟类,目前只用过AlarmManager.RTC_WAKEUP类型,这个是精确定时,很多博客都提到过,不了解的可以自己查查。然后action用来启动服务或者广播,alarmId就是requestCode,用来区别不同的闹钟。该工具类不仅仅可以用来定时通知,只要稍加改动,定时广播、定时任务、定时弹窗都是可以做的。
通知工具类
import android.app.Notification;
import android.app.NotificationChannel