无法将PluginRegistry转换为FlutterEngine


22

将flutter更新到1.12.13版后,我立即发现了此问题,无法解决。我按照firebase_messaging教程的指示发送了错误消息:“错误:不兼容的类型:PluginRegistry无法转换为FlutterEngine GeneratedPluginRegistrant.registerWith(注册表);”我的代码如下:

package io.flutter.plugins;

import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;

public class Application extends FlutterApplication implements PluginRegistrantCallback {
  @Override
  public void onCreate() {
    super.onCreate();
    FlutterFirebaseMessagingService.setPluginRegistrant(this);

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
      NotificationChannel channel = new NotificationChannel("messages","Messages", NotificationManager.IMPORTANCE_LOW);
  NotificationManager manager = getSystemService(NotificationManager.class);
  manager.createNotificationChannel(channel);
    }
  }

  @Override
  public void registerWith(PluginRegistry registry) {
    GeneratedPluginRegistrant.registerWith(registry);
  }
}

即时通讯也收到此错误。有什么解决办法吗?
ajonno

不,我尝试了但不能尝试
Gabriel G. Pavan

Answers:


21

于2019年12月31日更新。

您不应使用Firebase云消息传递工具发送通知,因为它会迫使您使用标题和正文。

您必须发送不带标题和正文的通知。在后台运行该应用程序,它将为您工作。

如果它对您有用,请您对这个答案投我一票,谢谢。


我找到了一个临时解决方案。我不确定这是否是最佳解决方案,但是我的插件可以按预期工作,并且我认为问题必须出在第164行上的io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService提供的注册表中。

我的AndroidManifest.xml文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="Your Package"> // CHANGE THIS

    <application
        android:name=".Application"
        android:label="" // YOUR NAME APP
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        <!-- BEGIN: Firebase Cloud Messaging -->    
            <intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        <!-- END: Firebase Cloud Messaging -->    
        </activity>
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

我的Application.java

package YOUR PACKAGE HERE;

import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;

public class Application extends FlutterApplication implements PluginRegistrantCallback {

  @Override
  public void onCreate() {
    super.onCreate();
    FlutterFirebaseMessagingService.setPluginRegistrant(this);
  }

  @Override
  public void registerWith(PluginRegistry registry) {
    FirebaseCloudMessagingPluginRegistrant.registerWith(registry);
  }
}

我的FirebaseCloudMessagingPluginRegistrant.java

package YOUR PACKAGE HERE;

import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;

public final class FirebaseCloudMessagingPluginRegistrant{
  public static void registerWith(PluginRegistry registry) {
    if (alreadyRegisteredWith(registry)) {
      return;
    }
    FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
  }

  private static boolean alreadyRegisteredWith(PluginRegistry registry) {
    final String key = FirebaseCloudMessagingPluginRegistrant.class.getCanonicalName();
    if (registry.hasPlugin(key)) {
      return true;
    }
    registry.registrarFor(key);
    return false;
  }
}

用dart发送通知:

Future<void> sendNotificationOnBackground({
  @required String token,
}) async {
  await firebaseMessaging.requestNotificationPermissions(
    const IosNotificationSettings(sound: true, badge: true, alert: true, provisional: false),
  );
  await Future.delayed(Duration(seconds: 5), () async {
    await http.post(
    'https://fcm.googleapis.com/fcm/send',
     headers: <String, String>{
       'Content-Type': 'application/json',
       'Authorization': 'key=$SERVERTOKEN', // Constant string
     },
     body: jsonEncode(
     <String, dynamic>{
       'notification': <String, dynamic>{

       },
       'priority': 'high',
       'data': <String, dynamic>{
         'click_action': 'FLUTTER_NOTIFICATION_CLICK',
         'id': '1',
         'status': 'done',
         'title': 'title from data',
         'message': 'message from data'
       },
       'to': token
     },
    ),
  );
  });  
}

我添加了一个等待时间,持续时间为5秒,因此您可以将应用程序置于后台,并验证后台消息是否正在运行


我尝试了您的解决方案,但未成功,但在ONLAUNCH,ONRESUME和ONMESSAGE状态下出现,仅在ONBACKGROUND上没有。我将文件FirebaseCloudMessagingPluginRegistrant.java与Application.java放在同一文件夹中,对吗?我希望Flutter小组能尽快解决这个问题。到那时,我将不得不使用1.9.1版本,尽管我想如此严重地使用1.12.13
Gabriel G. Pavan

您能否创建一个项目,并在我的github上给我链接,以供我下载并尝试在Firebase测试项目上运行它?
加布里埃尔·G·帕万

我已经更新了答案,但我错过了要补充的重要事实。
DomingoMG,

我留下的结构可以帮助我用飞镖发送推送通知
DomingoMG

这工作了。不知道为什么,但是确实如此。希望扑扑团队在下一版本中解决此问题
Avi

10

以下是DomingoMG到Kotlin的代码移植。经过测试并于2020年3月开始工作。

pubspec.yaml

firebase_messaging: ^6.0.12

应用程序

package YOUR_PACKAGE_HERE

import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService

public class Application: FlutterApplication(), PluginRegistrantCallback {
  override fun onCreate() {
    super.onCreate()
    FlutterFirebaseMessagingService.setPluginRegistrant(this)
  }

  override fun registerWith(registry: PluginRegistry) {
    FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
  }
}

FirebaseCloudMessagingPluginRegistrant.kt

package YOUR_PACKAGE_HERE

import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin

class FirebaseCloudMessagingPluginRegistrant {
  companion object {
    fun registerWith(registry: PluginRegistry) {
      if (alreadyRegisteredWith(registry)) {
        return;
      }
      FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"))
    }

    fun alreadyRegisteredWith(registry: PluginRegistry): Boolean {
      val key = FirebaseCloudMessagingPluginRegistrant::class.java.name
      if (registry.hasPlugin(key)) {
        return true
      }
      registry.registrarFor(key)
      return false
    }
  }
}

嗨,```执行任务':app:mergeDexDebug'失败。>执行com.android.build.gradle.internal.tasks.Workers $ ActionFacade时发生故障> com.android.builder.dexing.DexArchiveMergerException:合并dex归档时出错:在developer.android.com上了解如何解决此问题/ studio / build /…。节目类型已经存在:com.example.gf_demo.FirebaseCloudMessagingPluginRegistrant```
卡米尔

7

替换下面的代码行:

GeneratedPluginRegistrant.registerWith(registry);

有了这个:

FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));

1
它起作用了……只是记得导入提到的类。导入io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
锡安

1

除了DomingoMG的答案,别忘了删除

@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);

从android文件夹下的mainactivity文件中。如果没有,您将得到一个错误。


但是,当我删除configureFlutterEngine时,可以在哪里注册我自己的MethodChannel?
卡米尔·斯沃博达

根据DomingoMG的回答,FirebaseCloudMessagingPluginRegistrant.java已经进行了“ registerWith ...”的注册,因此这就是不再需要configureFlutterEngine的原因。这是否回答你的问题?
Axes Grinds

我了解FirebaseCloudMessagingPluginRegistrant.java会执行注册,而不是configureFlutterEngine。但是configureFlutterEngine是我可以注册自己的MethodChannel调用本地API的地方(请参阅flutter.dev上的“编写自定义平台特定的代码”)。删除方法configureFlutterEngine时,在哪里可以注册MethodChannel?
卡米尔·斯沃博达

我没有编写平台特定代码的经验。抱歉,我无法提供这些信息。希望您能找到答案。
Axes Grinds

1

我从Firebase Messaging程序包的步骤中仅添加了额外的水类,此问题已解决:

import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
public final class FirebaseCloudMessagingPluginRegistrant{
public static void registerWith(PluginRegistry registry) {
    if (alreadyRegisteredWith(registry)) {
        return;
    }
    FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}

private static boolean alreadyRegisteredWith(PluginRegistry registry) {
    final String key = FirebaseCloudMessagingPluginRegistrant.class.getCanonicalName();
    if (registry.hasPlugin(key)) {
        return true;
    }
    registry.registrarFor(key);
    return false;
}}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.