android - 如何在 Kotlin 的 Fragment 中使用 Android AlarmManager?

标签 android kotlin broadcastreceiver alarmmanager receiver

我似乎无法让 AlarmManager 在 Fragment 中工作。我的接收者的 onReceive() 方法永远不会被执行。我假设我可能以错误的方式使用上下文,但我又无法让它在 Activity 中工作。我还在我的 list 中注册了接收器。

MyFragment.kt

class MyFragment : Fragment() {

...

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        super.onViewCreated(view, savedInstanceState)

        var alarmMgr: AlarmManager? = null
        lateinit var alarmIntent: PendingIntent

        alarmMgr = context!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmIntent = Intent(context, Receiver::class.java).let { intent ->

                PendingIntent.getService(context, 0, intent, 0)

        }

        val calendar: Calendar = Calendar.getInstance().apply {

        timeInMillis = System.currentTimeMillis()

        // The EditText includes a time in 24-hour format (e.g. 12:34)
        set(Calendar.HOUR_OF_DAY, editText.text.toString().substringBefore(":").toInt())
        set(Calendar.MINUTE, editText.text.toString().substringAfter(":").toInt())

        }

        Log.d("ALARM", "CREATED")

        alarmMgr?.set(
              AlarmManager.RTC,
              calendar.timeInMillis,
              alarmIntent
        )

    }

}

Receiver.kt

class Receiver : BroadcastReceiver() {

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

        Log.d("ALARM", "RECEIVED")

    }

}

AndroidManifest.xml

<application
...
    <receiver android:name="com.example.name.Receiver" />
</application>

最佳答案

要事第一:

AndroidManifest.xml

<receiver
  android:name="com.example.name.Receiver"
  android:enabled="true"
  android:exported="true">
   <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
   </intent-filter>
</receiver>

然后,在这种情况下,在您的 Fragment 中,我建议在其他地方执行此操作:

val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(context, Receiver::class.java)

// Used for filtering inside Broadcast receiver
intent.action = "MyBroadcastReceiverAction"
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0)

// In this particular example we are going to set it to trigger after 30 seconds.
// You can work with time later when you know this works for sure.
val msUntilTriggerHour: Long = 30000
val alarmTimeAtUTC: Long = System.currentTimeMillis() + msUntilTriggerHour

// Depending on the version of Android use different function for setting an 
// Alarm.
// setAlarmClock() - used for everything lower than Android M
// setExactAndAllowWhileIdle() - used for everything on Android M and higher
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
  alarmManager.setAlarmClock(
  AlarmManager.AlarmClockInfo(alarmTimeAtUTC, pendingIntent),
  pendingIntent
  )
} else {
  alarmManager.setExactAndAllowWhileIdle(
  AlarmManager.RTC_WAKEUP,
  alarmTimeAtUTC,
  pendingIntent
  )
}

然后在您的广播接收器中,我们执行以下操作:

class Receiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        // We use this to make sure that we execute code, only when this exact 
        // Alarm triggered our Broadcast receiver
        if (intent?.action == "MyBroadcastReceiverAction") {
           Log.d("ALARM", "RECEIVED")
        }
    }
}

关于android - 如何在 Kotlin 的 Fragment 中使用 Android AlarmManager?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64268402/

相关文章:

android - 将多种样式应用于单个文本 - Jetpack Compose

kotlin - 从HashMap打印值

android - Kotlin/Native-> androidMain->无法解析的符号

android - Pepper QISDK同步调用是否可以确保结果?

android - 如何将自定义 Intent 过滤器注册到 AndroidManifest.xml 中的广播接收器?

java - 如何在 Oreo (8.0) 中使用隐式广播 PACKAGE_ADDED?

Android 4.4.2 & 软键盘。选项菜单是可能的?发生 "Unimplemented WebView method onKeyDown called from"

android - 尝试转到新的Intent时,Android App崩溃

android - 指定为非空的参数为空 : method kotlin. jvm.internal.Intrinsics.checkParameterIsNotNull,参数 convertView

android - 接收器上的 "Exported receiver does not require permission"意味着从系统服务接收