android 如何在完全退出APP后延时调出通知,实现定时推送信息到通知栏
很好,项目总监在我开心的YY的时候过来提了一个需求:当游戏退出时,请注意不是退出后台,是完全退出的那种,你给加个功能:8小时后弹出通知,你要赶紧起来玩游戏了,睡什么睡!!! 好强盗,上有政策,中有孙策,下有玄策,好嘛,这把开局有点难打,那么开干吧,看在钱的面子上------
实现定时推送信息到通知栏
分析:
1.如何触发通知,那肯定是广播啦(注意:Android p 不支持静态广播了,嘤嘤嘤).
2.如何保证触发,开服务?好像不行,好多人说设前台,还有二保一,看的头晕,谷歌笑脸.
3.定时处理,8小时内,重新进入游戏,取消上次的触发通知.
实现:
1.当然是注册一个广播接收器
NotificationReceiver :
public class NotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.example.yy.game_notification")) {
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
Notification notify = new Notification.Builder(context)
.setSmallIcon(R.drawable.icon)
.setTicker("TickerText:" + "睡什么睡 ** 起来嗨!")
.setContentTitle("温馨提示:")
.setContentText(""睡什么睡 ** 起来嗨!")
.setContentIntent(pendingIntent).setNumber(1).build();
notify.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager manager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(1, notify)
}
}
}
2.调用 AlarmManager (使用方法自行百度),设置一个闹钟,定时发送一个广播
public void setAlarmOnetoNotification(int time, boolean issetalarm) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent();
intent.setAction("com.example.yy.game_notification");
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0x101, intent, 0);
if (issetalarm) {
long triggerAtTime = SystemClock.elapsedRealtime() + time; //获取手机开机到现在的时间 加上你要延时的时间
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);//未设提醒,设置提醒
} else{
alarmManager.cancel(pendingIntent);//已设提醒,取消之前提醒,重新设置
}
3.在退出(exit)游戏的地方加入判断,保留时间戳用做判断(本人在此处画蛇添足了)
if (getExitGameTime() == null) {
setAlarmOnetoNotification(GAME_NOTIFICATION_TIME, true);//传入你要定时的时长以及是否是已设置
saveExitGameTime(System.currentTimeMillis());
} else {
setAlarmOnetoNotification(GAME_NOTIFICATION_TIME, false);
setAlarmOnetoNotification(GAME_NOTIFICATION_TIME, true);
}
小方法:保留时间戳:
public void saveExitGameTime(long exittime) {
SharedPreferences sharedPreferences = getSharedPreferences("ExitGametime", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("currentExitTime", stampToDate(exittime));
editor.commit();
}
public String getExitGameTime() {
SharedPreferences sharedPreferences = getSharedPreferences("ExitGametime", Context.MODE_PRIVATE);
String str = sharedPreferences.getString("currentExitTime", null);
return str;
}
/**
* 将时间转换为时间戳
*/
public String dateToStamp(String time) throws ParseException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse(time);
long ts = date.getTime();
return String.valueOf(ts);
}
/**
* 将时间戳转换为时间
*/
public String stampToDate(long timeMillis) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(timeMillis);
return simpleDateFormat.format(date);
}
目前自测OK,退出后两小时后弹出提示
有大神说:改变时区,可能AlarmManager 设置的闹钟就不起作用了,然后关机后好像也不起作用,嗯,先跟项目总监说说…
代码参考:https://blog.csdn.net/myfwjy/article/details/51726072
本人经验不足(第一篇博客),有问题(肯定有问题)欢迎指出,互相学习…
第一次补充:
Android 一直在更新,有人说定时会随着版本升高而不准确
于是我看了一下定时的type:
得嘞,要版本适配了:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);//未设提醒,设置提醒
} else {
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);//未设提醒,设置提醒
}
网上有超级多的适配,可以参考一下
那么说一下我碰到问题:
在虚拟机上定时有效果(想怎么来就怎么来),在真机上,4小时有效果(app在后台,不退出的情况),8小时没有效果(猜测被后台进程杀死了),退出app,没有效果----掀桌
找了很多资料,也尝试过,没有效果,后来发现一位大神说:
关于Android中的AlarmManager使用后不唤醒的问题:
https://blog.csdn.net/qq_38679144/article/details/78867210
姑且再试试…
分析问题出现原因:系统禁止了该应用的自启动
本人用的是小米测试机,在设置中有一项自启动管理,开启授权app后,8小时定时弹出通知有效,代码功能OK,这也就可以解释另一个问题,为什么手机自带的闹钟可以有效定时,自带系统权限
市场上许多应用为啥能在应用结束后还能推送消息呢?据说是接入了推送sdk…