Flutter:带有 patform 通道的 Firebase 消息传递 - 重复的 FlutterActivity

Posted

技术标签:

【中文标题】Flutter:带有 patform 通道的 Firebase 消息传递 - 重复的 FlutterActivity【英文标题】:Flutter: Firebase messaging with patform channels - Duplicated FlutterActivity 【发布时间】:2020-05-10 18:20:44 【问题描述】:

我正在尝试使用 Flutter 实现一个应用程序。该应用程序应该能够使用 FCM 从智能手机向服务器发送消息,或通过 FCM 从服务器接收消息。 我使用 firebase_messaging 插件 (https://pub.dev/packages/firebase_messaging) 实现了 FCM 功能。下游消息(服务器->设备)一切正常。现在我尝试添加上游消息(设备-> 服务器)。据我从文档中了解到,该插件尚不支持上游消息。所以我开始编写本机代码将消息发送到服务器并通过平台通道功能调用此代码(https://flutter.dev/docs/development/platform-integration/platform-channels?tab=android-channel-kotlin-tab)。

初始 MainActivity.kt:

import android.os.Bundle

import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterActivity() 
  override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)
    GeneratedPluginRegistrant.registerWith(this)
  

添加了 Flutter 文档中的方法通道示例。使用 Flutter 文档中指定的导入:

    private val CHANNEL = "samples.flutter.dev/battery"
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) 
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler 
            // Note: this method is invoked on the main thread.
            call, result ->
            if (call.method == "getBatteryLevel") 
                val batteryLevel = getBatteryLevel()

                if (batteryLevel != -1) 
                    result.success(batteryLevel)
                 else 
                    result.error("UNAVAILABLE", "Battery level not available.", null)
                
             else 
                result.notImplemented()
            
        
    

    private fun getBatteryLevel(): Int 
        val batteryLevel: Int
        if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) 
            val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
            batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
         else 
            val intent = ContextWrapper(applicationContext).registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
            batteryLevel = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
        
        return batteryLevel
    

但不幸的是出现了问题。 firebase_messaging 插件需要 mainactivity.kt 扩展 io.flutter.app.FlutterActivity。平台频道需要 mainactivity.kt 扩展 io.flutter.embedding.android.FlutterActivity

有什么方法可以同时使用 - firebase_messaging 插件和方法通道?

【问题讨论】:

【参考方案1】:

我将我的代码与 firebase_messaging 插件中的示例项目进行了比较:https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_messaging/example/android/app/src/main/java/io/flutter/plugins/firebasemessagingexample/MainActivity.java

然后我意识到该示例也使用了io.flutter.embedding.android.FlutterActivity。将导入语句更改为io.flutter.embedding... 包后,我删除了GeneratedPluginRegistrant.registerWith(this),因为GeneratedPluginRegistrant 是来自io.flutter.plugins.GeneratedPluginRegistrant 的导入,并且似乎与嵌入包不匹配。然后我再次检查了io.flutter.embedding.engine.FlutterEngine中的字段和函数并添加了以下行:flutterEngine?.plugins?.add(FirebaseMessagingPlugin())

在此之后,我重新编译了应用程序,并在启动时成功打印出 FCM 设备 ID 和电池状态。

import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.Bundle
import androidx.annotation.NonNull
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin

class MainActivity : io.flutter.embedding.android.FlutterActivity() 

    private val CHANNEL = "samples.flutter.dev/battery"

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        flutterEngine?.plugins?.add(FirebaseMessagingPlugin())
    

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) 
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler 
            // Note: this method is invoked on the main thread.
            call, result ->
            if (call.method == "getBatteryLevel") 
                val batteryLevel = getBatteryLevel()

                if (batteryLevel != -1) 
                    result.success(batteryLevel)
                 else 
                    result.error("UNAVAILABLE", "Battery level not available.", null)
                
             else 
                result.notImplemented()
            
        
    

    private fun getBatteryLevel(): Int 
        val batteryLevel: Int
        if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) 
            val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
            batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
         else 
            val intent = ContextWrapper(applicationContext).registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
            batteryLevel = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
        
        return batteryLevel
    

【讨论】:

以上是关于Flutter:带有 patform 通道的 Firebase 消息传递 - 重复的 FlutterActivity的主要内容,如果未能解决你的问题,请参考以下文章

MissingPluginException(在通道 flutter_email_sender 上找不到方法发送的实现)

将 java.security.auth.login.config 传递给 Mobilefirst Patform Server

Flutter iOS 和 Android 中的 FCM 自定义声音

Android Wi-Fi/Cellular多网络通道绑定方案对比

Android Wi-Fi/Cellular多网络通道绑定方案对比

Flutter中FCM的自定义通知通道