【问题标题】:Proper way to create and access BroadcastReceiver inside MainActivity? (Kotlin)在 MainActivity 中创建和访问 BroadcastReceiver 的正确方法? (科特林)
【发布时间】:2021-10-17 09:58:27
【问题描述】:

在 Activity 中为警报管理器创建和使用 BroadcastReceiver 的正确方法是什么?

我确实看过以下答案,但我不清楚是否需要注册广播接收器以及如何使用 AlarmManager 进行注册(如果是)。另外,我不清楚我是应该在 OnCreate() 函数内还是作为类变量创建 BroadcastReceiver。

Broadcast Receiver in kotlin

Kotlin AlarmManager and BroadcastReceiver not working


背景:

我正在尝试制作一个应用程序:

  1. 在特定时间播放歌曲

  2. 更新下次播放歌曲的时间

我能够通过为 BroadcastReceiver 文件创建一个单独的文件来实现 1) 工作,就像通常所做的那样,但是我无法访问 AlarmManager,因为它仅在 AppCompatActivity 类中可用。我还尝试使用意图移回主要活动并在那里设置新警报,但这也确实有效,因为 BroadcastReceiver 没有上下文。

我现在尝试在 MainActivity 中设置 BroadcastReceiver,但它没有被触发:

private lateinit var picker: MaterialTimePicker
private lateinit var alarmManager: AlarmManager
private lateinit var calendar: Calendar

val broadCastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        var mp = MediaPlayer.create(context, R.raw.song_title)

        mp.setVolume(1.0f, 1.0f)
        mp.start()
    }
}

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

    var calendar = Calendar.getInstance()

    val intent = Intent(this, MainActivity::class.java)
    val pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0)
    alarmManager = getSystemService(ALARM_SERVICE) as AlarmManager

    val newDate = Calendar.getInstance()
    newDate.add(Calendar.MINUTE, 1)

    calendar[java.util.Calendar.HOUR_OF_DAY] = newDate.get(Calendar.HOUR_OF_DAY)
    calendar[java.util.Calendar.MINUTE] = newDate.get(Calendar.MINUTE)
    calendar[java.util.Calendar.SECOND] = 0
    calendar[java.util.Calendar.MILLISECOND] = 0

    alarmManager.setAndAllowWhileIdle(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        pendingIntent
    )


}

}

【问题讨论】:

  • 为什么不通过构造函数将AlarmManager 传递给单独文件中的BroadcastReceiver
  • @gtxtreme 我不确定它是如何工作的。当您从 MainActivity 到另一个文件执行挂起意图时,您正在实例化该类,所以我认为您不能将 AlarmManager 作为构造函数传递。
  • 哦,是的,我的错,但这段代码应该可以工作,我想让我试着找出问题所在
  • @nayriz 您能否具体说明您想要实现的目标?
  • @akhilnair 我想在给定时间播放一首歌曲,每次播放歌曲时,使用特殊功能设置下一次播放歌曲的时间。例如: 1. 触发媒体播放器在 13:00 播放歌曲。同时设置媒体播放器在 13:14 播放同一首歌曲 2. 触发媒体播放器播放 13:14 的歌曲。同时设置媒体播放器在13:26等播放同一首歌曲...(用于选择下一个时间的功能无关)

标签: android android-studio kotlin


【解决方案1】:

AlarmManager 不仅在 AppCompatActivity 类中可用,而且在您可以访问 Context 的任何地方都可用,如下所示:

class MyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
    val alarmManager = context?.getSystemService(ALARM_SERVICE) as AlarmManager
  }
}

【讨论】:

  • 我已经添加了一个答案,如果这是你需要的,请告诉我。
  • 您的解决方案适用于最终目的,但是由于我还需要从主要活动更新 UI,我还必须使用意图返回主要活动。这是糟糕的编码,所以我仍然希望将广播接收器放在 MainActivity 中。我可以创建一个新问题“如何在 BroadCasr 接收器中使用 AlarmManager”,我会在那里接受您的回答。
【解决方案2】:

在调整 this answer 之后,我让它工作了:

class MainActivity : ComponentActivity() {

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

        val receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                var TAG = "check"
                Log.i(TAG,"==============")
                Log.i(TAG,"inside receiver")
                Log.i(TAG,"==============")
            }
        }

        this.registerReceiver(receiver, IntentFilter("TEST"))

        val intent = Intent()
        intent.action = "TEST"

        val alarmManager = this.getSystemService(ALARM_SERVICE) as? AlarmManager
        val pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0)

        val calendar = Calendar.getInstance()

        calendar.add(Calendar.SECOND, 10)

        alarmManager?.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)
        
    }
}

我可以确认确实需要注册接收器。

【讨论】:

  • 您不需要在某个时间点取消注册接收器吗?
  • @akhilnair 我猜你会的,这一次我只是想让接收器首先工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
  • 2022-11-16
  • 2021-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多