Flutter 重新启动设备后,在颤振中调用方法

Flutter 重新启动设备后,在颤振中调用方法,flutter,dart,Flutter,Dart,我构建了一个待办事项列表应用程序,它应该显示提醒任务的通知。为了能够将通知安排到截止日期的准确时间,我将通知数据从flifter传递到kotlin,并显示来自广播接收器的通知 在这里,我将通知数据发送给kotlin: await platform.invokeMethod('setNextNotification', { 'tasksNames': tasksNames, 'notificationsTimeInMillis': notificationsTimeInM

我构建了一个待办事项列表应用程序,它应该显示提醒任务的通知。为了能够将通知安排到截止日期的准确时间,我将通知数据从flifter传递到kotlin,并显示来自广播接收器的通知

在这里,我将通知数据发送给kotlin:

 await platform.invokeMethod('setNextNotification', {
      'tasksNames': tasksNames,
      'notificationsTimeInMillis': notificationsTimeInMillis
    });
以下是我获取活动中数据的方式:

private const val CHANNEL = "flutter.native/helper"

class MainActivity : FlutterActivity() {

companion object {
    const val TASKS_NAMES_EXTRA = "tasksNames"
    const val NOTIFICATIONS_TIME_IN_MILLIS_EXTRA = "notificationsTimeInMillis"

}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    GeneratedPluginRegistrant.registerWith(this)

    // Init the AlarmManager.
    val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager

    // We got here from the setNotifications() method in flutter...
    MethodChannel(flutterView, CHANNEL).setMethodCallHandler { call, result ->
        if (call.method == "setNextNotification") {

            // Get the time till next notification
            val notificationsTimeInMillis: ArrayList<Long> = call.argument(NOTIFICATIONS_TIME_IN_MILLIS_EXTRA)
                    ?: ArrayList()

            // Create a pending intent for the notifications
            val pIntent: PendingIntent? = createPendingIntent(call.argument(TASKS_NAMES_EXTRA), call.argument(TIME_LEFT_TEXTS_EXTRA), notificationsTimeInMillis, this)

            // Cancel all alarms
            while (alarmManager.nextAlarmClock != null)
                alarmManager.cancel(alarmManager.nextAlarmClock.showIntent)

            // Set the alarm
            setAlarm(notificationsTimeInMillis[0], pIntent, alarmManager)

        } 
    }
}

private fun setAlarm(notificationTime: Long, pIntent: PendingIntent?, alarmManager: AlarmManager) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // The API is 23 or higher...
        alarmManager.setAlarmClock(AlarmManager.AlarmClockInfo(notificationTime, pIntent), pIntent)
    } else { // The API is 19 - 22...
        // We want the alarm to go of on the exact time it scheduled for so we use the setExact method.
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, notificationTime, pIntent)
    }

}

private fun createPendingIntent(tasksNames: ArrayList<String>?, timeTillNotificationsInMillis: ArrayList<Long>?,
                                context: Context): android.app.PendingIntent? {

  
    return try {

        val intent: android.content.Intent = android.content.Intent(context, AlarmManagerHelperWakeful::class.java)
        intent.action = "notification"
     
        intent.putStringArrayListExtra(TASKS_NAMES_EXTRA, tasksNames)
        intent.putStringArrayListExtra(NOTIFICATIONS_TIME_IN_MILLIS_EXTRA, timeTillNotificationsInMillisAsString)
        android.app.PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
    } catch (e: java.lang.Exception) {
        null
    }
}
private const val CHANNEL=“flatter.native/helper”
类MainActivity:activity(){
伴星{
const val TASKS\u NAMES\u EXTRA=“tasksNames”
const val NOTIFICATIONS\u TIME\u IN\u MILLIS\u EXTRA=“notificationsTimeInMillis”
}
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
//初始化AlarmManager。
val alarmManager=getSystemService(Context.ALARM\u服务)作为alarmManager
//我们是从Flatter中的setNotifications()方法得到的。。。
MethodChannel(FlatterView,CHANNEL).setMethodCallHandler{call,result->
if(call.method==“setNextNotification”){
//获取下次通知的时间
val notificationsTimeInMillis:ArrayList=call.argument(通知\时间\单位:毫秒\额外)
?:ArrayList()
//为通知创建挂起的意图
val pIntent:pendingent?=creatependingent(call.argument(TASKS\u NAMES\u EXTRA)、call.argument(TIME\u LEFT\u text\u EXTRA)、notificationstimeinmills、this)
//取消所有警报
while(alarmManager.nextAlarmClock!=null)
alarmManager.cancel(alarmManager.nextAlarmClock.showIntent)
//设置警报
设置报警(notificationsTimeInMillis[0],pIntent,alarmManager)
} 
}
}
私人娱乐设置报警(通知时间:长,pIntent:pendingent?,报警管理器:报警管理器){
如果(Build.VERSION.SDK\u INT>=Build.VERSION\u CODES.M){//API为23或更高。。。
alarmManager.setAlarmClock(alarmManager.AlarmClockInfo(notificationTime,pIntent),pIntent)
}否则{//API是19-22。。。
//我们希望警报在预定的准确时间发出,因此我们使用setExact方法。
alarmManager.setExact(alarmManager.RTC_唤醒、通知时间、pIntent)
}
}
private fun CreatePendingEvent(任务名称:ArrayList?,timeTillNotificationsInMillis:ArrayList?,
context:context):android.app.pendingent{
回击{
val intent:android.content.intent=android.content.intent(上下文,AlarmManagerHealpWakeful::class.java)
intent.action=“通知”
intent.putStringArrayListExtra(任务\名称\额外,任务名称)
intent.putStringArrayListExtra(通知以毫秒为单位,时间到通知以毫秒为单位)
android.app.pendingent.getBroadcast(上下文,0,意图,pendingent.FLAG_UPDATE_CURRENT)
}catch(e:java.lang.Exception){
无效的
}
}
}

这就是我在BroadcastReceiver上显示通知的方式,然后设置下一个通知:

Class AlarmManagerHelperWakeful : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {

    if (intent != null && intent.action == "notification" && context != null) {
        
       
        val tasksLabels: ArrayList<String> = intent.getStringArrayListExtra(MainActivity.TASKS_NAMES_EXTRA)
                ?: ArrayList()

        val notificationsTimeInMillisAsString: ArrayList<String> = intent.getStringArrayListExtra(MainActivity.NOTIFICATIONS_TIME_IN_MILLIS_EXTRA)
                ?: ArrayList()

        if (tasksLabels.size > 0) {
          
            // Create a notification manager.
            val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            var builder = NotificationCompat.Builder(context) // The initialization is for api 25 or lower so it is deprecated.


            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // This is API 26 or higher...
                // Create a channel for API 26 or higher;
                val channelId = "channel_01" // The id of the channel.
                if (notificationManager.getNotificationChannel(channelId) == null) {
                    val channel = NotificationChannel(channelId,
                            context.getString(R.string.notification_channel_name),
                            NotificationManager.IMPORTANCE_DEFAULT)
                    notificationManager.createNotificationChannel(channel)

                }
                // Update the builder to a no deprecated one.
                builder = NotificationCompat.Builder(context, channelId)
            }

            // Set the notification details.
            builder.setSmallIcon(android.R.drawable.ic_notification_overlay)
            builder.setContentTitle(tasksLabels[0])
            builder.setContentText(someText)
            builder.priority = NotificationCompat.PRIORITY_DEFAULT

            notificationId = someUniqueId

            // Show the notification.
            notificationManager.notify(notificationId.toInt(), builder.build())

            // Remove this notification from the notifications lists.
            tasksLabels.removeAt(0)
            notificationsTimeInMillisAsString.removeAt(0)

            // There are more notifications...
            if (tasksLabels.size > 0) {

                // Init the AlarmManager.
                val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager

                // Cancel all alarms
                while (alarmManager.nextAlarmClock != null)
                    alarmManager.cancel(alarmManager.nextAlarmClock.showIntent)

                // Create a pending intent for the notifications
                val pIntent: PendingIntent? = createPendingIntent(tasksLabels, cnotificationsTimeInMillisAsString, context)

                // Set the alarm
                setAlarm(notificationsTimeInMillisAsString[0].toLong(), pIntent, alarmManager)

            }

        }

    } else {
        if (intent == null) {
            Log.d("Debug", "Checking: intent == null")
        } else if ( intent.action != "notification") {
            Log.d("Debug", "Checking: intent.action != notification")
            val tasksLabels: ArrayList<String> = intent.getStringArrayListExtra(MainActivity.TASKS_NAMES_EXTRA)
                    ?: ArrayList()
            Log.d("Debug", "Checking: tasksNames.size inside else if" + tasksLabels.size)
        }
    }

}
}
类AlarmManagerHelperWakeful:BroadcastReceiver(){
覆盖接收(上下文:上下文?,意图:意图?){
if(intent!=null&&intent.action==“通知”&&context!=null){
val tasksLabels:ArrayList=intent.getStringArrayListExtra(MainActivity.TASKS\u name\u EXTRA)
?:ArrayList()
val NotificationStimeinMillisString:ArrayList=intent.getStringArrayListExtra(MainActivity.NOTIFICATIONS\u TIME\u IN\u MILLIS\u EXTRA)
?:ArrayList()
如果(tasksLabels.size>0){
//创建通知管理器。
val notificationManager=context.getSystemService(context.NOTIFICATION\u服务)作为notificationManager
var builder=NotificationCompat.builder(context)//初始化是针对api 25或更低版本的,因此不推荐使用。
如果(Build.VERSION.SDK\u INT>=Build.VERSION\u CODES.O){//这是API26或更高版本。。。
//为API 26或更高版本创建通道;
val channelId=“channel_01”//频道的id。
if(notificationManager.getNotificationChannel(channelId)==null){
val通道=通知通道(通道ID,
context.getString(R.string.notification\u channel\u name),
通知管理器。重要性(默认值)
notificationManager.createNotificationChannel(频道)
}
//将生成器更新为无弃用版本。
builder=NotificationCompat.builder(上下文,channelId)
}
//设置通知详细信息。
builder.setSmallIcon(android.R.drawable.ic\u通知\u覆盖)
builder.setContentTitle(任务标签[0])
builder.setContentText(someText)
builder.priority=NotificationCompat.priority\u默认值
notificationId=someUniqueId
//显示通知。
notificationManager.notify(notificationId.toInt(),builder.build())
//从通知列表中删除此通知。
tasksLabels.removeAt(0)
NotificationStimeinMillisString.removeAt(0)
//有更多的通知。。。
如果(tasksLabels.size>0){
//初始化AlarmManager。
val alarmManager=context.getSystemService(context.ALARM\u服务)作为alarmManager
//取消所有警报
while(alarmManager.nextAlarmClock!=null)
alarmManager.cancel(alarmManager.nextAlarmClock.showIntent)
//为通知创建挂起的意图
val pIntent:PendingENT?=创建PendingENT(任务标签,