如何在flutter插件中使用接收器(BroadcastReceiver)? [英] How do you use receiver (BroadcastReceiver) in a flutter plugin?

查看:131
本文介绍了如何在flutter插件中使用接收器(BroadcastReceiver)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am building an application that requires some of the functionality of the Radar.io SDK, and so I decided to create plugin so after this project is over I can share the plugin with the rest of the Flutter Community. The problem is, I am not able to receive events in this plugin. This is important for the plugin since in order to receive events such as geolocation triggers and other background events this receiver needs to be receiving realtime information.

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

I have successfully implemented every function in their SDK for Android (using Kotlin) seen here https://radar.io/documentation/sdk, however, the receiver is not getting called when an event takes place. I know the device is being tracked since the location is updated in the Radar.io dashboard, however, the receiver is not executed at all when various events take place.

这里是文档告诉您如何在清单中注册接收器的信息.

Here is how the documentation tells you to register the receiver in the Manifest.

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

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

This would work for a standard application, however, when I register the receiver in the manifest the application does not look in the plugins directory which is where the receiver is located. Instead it looks in the applications android directory and returns an error that the data path could not be found. This causes the application to terminate.

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

To combat this issue I discovered that the receiver could be set programmatically so I decided to give that a shot.

在插件的主Kotlin文件中,我写了以下几行,以在 registerWith onAttachedToEngine 中执行.据我了解,这些基本上是onStart函数. registerWith 是保留用于与旧设备兼容的旧功能.

Inside the Plugin's main Kotlin file I wrote the following lines to be executed in the registerWith and the onAttachedToEngine. It is my understanding that these are basically the onStart functions. registerWith is an older function kept for compatibility with older devices.

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

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

The class referenced as MyRadarReceiver() is an extension of the RadarReceiver class in the SDK which extends BroadcastReceiver meaning this is my Broadcast Receiver. Here is the class:

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, location: Location, 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,如下所示:

When I started background tracking on the emulated device I expected one of the functions in MyRadarReceiver to execute, but nothing was printed to the terminal. There was no errors, but nothing was received. This makes me wonder if I set the intent incorrectly or if maybe the Receiver was written improperly. I don't know another way to set the intent so I decided to rewrite the MyRadarReceiver in a simpler form like so:

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

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

Unfortunately nothing was printed to the console so I now believe it has something to do with my intent.

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

The only solution I have left to try is to write the receiver in the application instead of in the plugin. This may work, however, I was hoping to share this plugin with the Flutter community when I was finished. Radar is a very powerful platform and bringing this plugin to the Flutter community could have an outstanding impact.

推荐答案

解决方案

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

After seeing the comment by Nitrodon I took a different look at the problem and found a solution. I am not sure why the programmatic Receiver initialization didn't work, however, here is what I put in my plugin's Android Manifest.

<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 的名称.希望这对其他人有所帮助!如果有人要添加任何内容,请这样做,但最终成功!

You cannot add an android label or anything else to the application tags or it will throw an error out of conflict with the application's Android Manifest. For this reason, you just need to declare the receiver in the simple application tags that only contain the name which is io.flutter.app.FlutterApplication. I hope this helps someone else! If anyone has anything to add please do but it finally works!

这篇关于如何在flutter插件中使用接收器(BroadcastReceiver)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆