我一直在尝试在我的应用中实施通知,但没有成功。以下是我的观察:
要求:
到目前为止,我如何解决该问题:
我创建了一个NotificationScheduler
对象,该对象基本上为要触发的通知创建了PendingIntent
。
object NotificationScheduler {
fun scheduleNotification(context: Context, model: Model, cal: Calendar) {
cal.set(Calendar.HOUR_OF_DAY, 11)
val notificationIntent = Intent(context, NotificationPublisher::class.java)
notificationIntent.putExtra("model", Utils.parcelToBytes(model))
val pendingIntent = PendingIntent.getBroadcast(context, 1, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.timeInMillis, pendingIntent)
}
}
然后我有一个NotificationPublisher
类,应该显示通知并通过再次调用NotificationScheduler
来设置下一个通知。
class NotificationPublisher: BroadcastReceiver() {
var model: Model? = null
override fun onReceive(context: Context?, intent: Intent?) {
val modelBytes = intent?.getByteArrayExtra("model")
if (modelBytes != null) {
model = Utils.bytesToParcel(modelBytes, Model.CREATOR)
}
val notificationBuilder = NotificationBuilder(context!!, model!!)
val notification = notificationBuilder.buildNotification()
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(1, notification)
//schedules the next notification
NotificationScheduler.scheduleNotification(context, model!!, Calendar.getInstance())
}
}
NotificationBuilder
类仅使用context
和model
并建立通知的地方
class NotificationBuilder(val context: Context, val model: Model) {
fun buildNotification(): Notification {
generateNotificationChannel(context)
val builder = NotificationCompat.Builder(context, "ID")
.setSmallIcon(R.drawable.sub)
.setContentTitle(model.title)
.setPriority(NotificationCompat.PRIORITY_HIGH)
return builder.build()
}
private fun generateNotificationChannel(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "Test"
val description = "description"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel("ID", name, importance)
channel.description = description
val notificationManager = context.getSystemService(NotificationManager::class.java)
notificationManager?.createNotificationChannel(channel)
}
}
这种方法的问题:
如果我在创建通知后立即有意显示通知,它将起作用,但是每当例如用户重新启动设备或终止进程时,我都会收到NullPointerException。调试时,我发现重新启动设备后,存储在notificationIntent
中NotificationScheduler
中onReceive()
中的数据在NotificationPublisher
的{{1}}中不再可用,并且因此将生成一个NPE。
我认为我在这种方法上做错了什么,我希望您能帮助我弄清楚如何实现上述要求。
答案 0 :(得分:2)
好吧..,我不会详细介绍您的编程问题,也不会帮助您发现错误。.但是我很敏锐地阅读了您的问题,并且也得到了问题及其解决方案.. !!这有点理论上的。但是,正如我所看到的,您的编程技巧是好的..所以您只需要方向和概念上的明确。
如果我故意在创建通知后立即显示通知,则可以使用此通知,但是只要用户
reboots
他的设备或kills
该进程,我都会收到NullPointerException。
这是问题的主要原因。每当系统重新启动或系统杀死该应用程序时。
是什么原因造成的...?
每当系统重新启动时,“ AlarmManager
设置的所有警报将不再保留,需要由应用程序重新安排”
那怎么解决...?
维护计划的警报表。系统一旦启动ON_BOOT_COMPLETE
,便会重新安排所有时间。
市场上大多数设备不会触发我的
ON_BOOT_COMPLETE
接收器.. !!
是的,如今大多数设备仅保留google
,facebook
,whatsapp
,twitter
,instagram
等主要公司的服务,其余所有设备其他的在引导时被丢弃。
为什么移动制造商这样做?
这是一项业务,因此还可以提高整个设备的性能和速度。如果他们不允许上述公司重启服务,那么没人会接这种电话。
对此有任何解决方案吗??
使用Firebase作业调度程序。让Google Play服务处理您的服务。
如果我错了或者需要对该问题进行进一步的澄清,我希望它可以帮助您并纠正我。谢谢
我建议您通过您的mainactivity context
创建一个作业计划作业,并让它处理将在every reboot
上开始执行作业的Google Play服务。该作业应通过适当的通知调用前台服务。并通过该前台服务再次调用intentservice
,它将通过从Sqlite表中逐个读取来re-schedule
alarms
。
即使您遵循此处建议的所有范例,也会有另一个问题。
Google Play在重新启动后无法启动我的前台服务.. !!
是的...,如帖子Marshmallow
和modified ROMs
(包括库存的Android和移动制造商修改的操作系统,如OxygenOs,FunTouchOs,ColorOs等。此列表永远也不会结束)。重启后,任何私有应用程序进程都不会进入内存。
现在我有没有办法解决这个问题...?
是。.向用户显示大胆而明亮的警报:
If You want to perform this app normally,
you must stop optimising battery for this
app from settings..!!
那是我们解决这些许多问题的方法。 了解它没有来自Google的完善文档,也没有示例代码,以防万一,如果您在实现任何
sub-point
方面需要任何帮助,我也会帮助您实现所有这些子点
感谢您的帮助