如何在flutter插件中使用接收器BroadcastReceiver?

问题描述

问题

我正在构建一个需要Radar.io SDK某些功能的应用程序,因此我决定创建插件,因此在该项目结束后,我可以与Flutter社区的其他成员共享该插件。问题是,我无法在此插件中接收事件。这对插件很重要,因为要接收诸如地理位置触发和其他背景事件之类的事件,此接收器需要接收实时信息。

我已经在https://radar.io/documentation/sdk中成功地实现了其Android版SDK(使用Kotlin)的所有功能,但是发生事件时未调用接收方。我知道该设备正在跟踪,因为Radar.io仪表板中的位置已更新,但是,发生各种事件时,接收器根本不会执行。

我尝试过的

文档是如何告诉您在清单中注册接收器的。

  <receiver
      android:name=".MyRadarReceiver"
      android:enabled="true"
      android:exported="false">
      <intent-filter>
          <action android:name="io.radar.sdk.RECEIVED" />
      </intent-filter>
  </receiver>

这适用于标准应用程序,但是,当我在清单中注册接收器时,该应用程序不会在接收器所在的插件目录中查找。相反,它会在应用程序的android目录中查找并返回一条错误消息,即找不到数据路径。这将导致应用程序终止。

为了解决这个问题,我发现可以通过编程方式设置接收器,所以我决定尝试一下。

插件的主Kotlin文件中,我编写了以下几行,分别在registerWithonAttachedToEngine中执行。据我了解,这些基本上是onStart函数registerWith是较旧的功能,为与较旧的设备兼容而保留。

val myRadarReceiver = MyRadarReceiver()
val intentFilter = IntentFilter()
intentFilter.addAction("io.radar.sdk.RECEIVED")
Contextwrapper(this.context).registerReceiver(myRadarReceiver,intentFilter)

引用为MyRadarReceiver()的类是SDK中RadarReceiver类的扩展,扩展了broadcastReceiver,这意味着这是我的广播接收器。这是课程:

public class MyRadarReceiver: RadarReceiver() {

  override fun onEventsReceived(context: Context,events: Array<RadarEvent>,user: RadarUser) {
    println("test: " + "an event was received")
  }

  override fun onLocationUpdated(context: Context,location: Location,user: RadarUser) {
    println("test: " + "location was updated")
  }

  override fun onClientLocationUpdated(context: Context,stopped: Boolean,source: Radar.RadarLocationSource) {
    println("test: " + "client location updated")
  }

  override fun onError(context: Context,status: Radar.RadarStatus) {
    println("test: " + status)
  }

  override fun onLog(context: Context,message: String) {
    println("test: " + message)
  }

}

当我在仿真设备上开始后台跟踪时,我希望MyRadarReceiver中的功能之一可以执行,但是没有任何内容打印到终端上。没有错误,但是什么也没收到。这使我想知道我是否正确设置了意图,或者接收器的书写方式是否不正确。我不知道设置意图的另一种方法,所以我决定以一种更简单的形式重写MyRadarReceiver,如下所示:

public class MyRadarReceiver: broadcastReceiver() {
  override fun onReceive(context: Context,intent: Intent) {
    println("works! Something was received")
  }
}

不幸的是,控制台上没有打印任何内容,所以我现在认为这与我的意图有关。

摘要

我要尝试的唯一解决方案是在应用程序中而不是在插件中编写接收器。这可能可行,但是,我希望在完成后与Flutter社区共享此插件。 Radar是一个非常强大的平台,将该插件引入Flutter社区可能会产生巨大的影响。

解决方法

解决方案

在看到Nitrodon的评论后,我对问题进行了另一番研究并找到了解决方案。我不确定为什么无法对接收器进行编程初始化,但是,这是我在插件的 Android清单中输入的内容。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.youorganization.yourproject">
  <application
    android:name="io.flutter.app.FlutterApplication">
    <receiver
      android:name=".MyRadarReceiver"
      android:enabled="true"
      android:exported="false">
        <intent-filter>
            <action android:name="io.radar.sdk.RECEIVED" />
        </intent-filter>
    </receiver>
  </application>
</manifest>

您无法在应用程序标签中添加android标签或其他任何内容,否则会由于与应用程序的Android清单冲突而引发错误。因此,您只需要在仅包含名称io.flutter.app.FlutterApplication的简单应用程序标签中声明接收方。我希望这可以帮助其他人!如果有人要添加任何内容,请这样做,但最终成功!