Flutter: обмен сообщениями в Firebase с патч-каналами - Дублированная FlutterActivity - PullRequest
0 голосов
/ 24 января 2020

Я пытаюсь реализовать приложение, используя Flutter. Приложение должно иметь возможность отправлять сообщения со смартфонов на сервер с помощью FCM или получать сообщения с сервера через FCM. Я реализовал функциональность FCM с помощью плагина firebase_messaging (https://pub.dev/packages/firebase_messaging). Все нормально работает для последующих сообщений (сервер -> устройство). Теперь я попытался добавить исходящие сообщения (устройство -> сервер). Насколько я знаю из документов, плагин пока не поддерживает исходящие сообщения. Поэтому я начал писать собственный код для отправки сообщений на сервер и вызывать этот код с помощью функции канала платформы (https://flutter.dev/docs/development/platform-integration/platform-channels?tab=android-channel-kotlin-tab).

Initial 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 Ответ

0 голосов
/ 27 января 2020

Я сравнил свой код с примером проекта из плагина 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 и состояние батареи.

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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...