最近在写一个信鸽推送的需求,项目要求是需要有一个10分钟的定时器,如果通知栏消息未点击的情况下需要每隔10分钟提醒一次,用到的是Android原生的 AlarmManager:
public class AlarmManagerUtils { public static void startAlarm(Context context, int seconds, USER_MESSAGE user_message, Class> cls, String action) { AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, cls); intent.setAction(action); Bundle bundle = new Bundle(); bundle.putSerializable("USER_MESSAGE",user_message); intent.putExtras(bundle); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); long triggerAtTime = SystemClock.elapsedRealtime(); manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime+1000, seconds * 1000, pendingIntent); // if (Build.VERSION.SDK_INT >= 19) { // manager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, seconds * 1000, pendingIntent); // } else { // manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, seconds * 1000, pendingIntent); // } } public static void cancleAlarm(Context context, Class> cls, String action) { AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, cls); intent.setAction(action); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); manager.cancel(pendingIntent); } }
实现方式同上,问题是初次接受到数据的时候用的是Bundle直接传递的一个序列化的对象,在广播接收器里面取值的时候get到的数据一直null,意外的是单纯的传递String 字符串没问题,同时传递字符串和序列化对象结果都是null。
直接上终极buff
public class AlarmManagerUtils { public static void startAlarm(Context context, int seconds, USER_MESSAGE user_message, Class> cls, String action) { AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, cls); intent.setAction(action); Bundle bundle = new Bundle(); bundle.putString("USER_MESSAGE", new Gson().toJson(user_message)); intent.putExtras(bundle); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); long triggerAtTime = SystemClock.elapsedRealtime(); manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime+1000, seconds * 1000, pendingIntent); // if (Build.VERSION.SDK_INT >= 19) { // manager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, seconds * 1000, pendingIntent); // } else { // manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, seconds * 1000, pendingIntent); // } } public static void cancleAlarm(Context context, Class> cls, String action) { AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, cls); intent.setAction(action); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); manager.cancel(pendingIntent); } }
试了一下公司有的测试手机,全部通过测试。
最后吐槽一下Google AlarmManager,真是不好用,手头上的华为手机特么第一次时间间隔就得10分钟 喷满屏幕血,再喷产品经理一脸血。