Android 上 Flutter 中 MethodChannel 的 MissingPluginException

问题描述 投票:0回答:1

当我尝试在 Flutter 中使用

MissingPluginException
在我的 Android 应用程序中发送短信时,遇到了
MethodChannel
。即使我已经正确实现了本机代码,应用程序也会在运行时抛出此错误。

错误

E/flutter (10616): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method sendSMS on channel channel_name)
E/flutter (10616): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:332:7)
E/flutter (10616): <asynchronous suspension>
E/flutter (10616): #1      SmsService.sendSms (package:muteify/services/sms_service.dart:8:30)
E/flutter (10616): <asynchronous suspension>
E/flutter (10616): #2      phoneStateBackgroundCallbackHandler (package:muteify/services/phone_state_bg_helper.dart:16:19)
E/flutter (10616): <asynchronous suspension>

Dart 代码(Flutter 侧):

import 'package:flutter/services.dart';

const platform = MethodChannel('channel_name');

class SmsService {
  Future<String?> sendSms(String phone, String message) async {
    try {
      final String? result = await platform.invokeMethod<String?>('sendSMS', {
        'phone': phone,
        'message': message,
      });
      print("SMS result:  $result");
      return result;
    } on PlatformException catch (e) {
      return "Failed to send SMS: '${e.message}'.";
    }
  }
}

MainActivity.kt(Android端):

@file:Suppress("DEPRECATION")

package com.example.muteify

import android.telephony.SmsManager
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.Result

class MainActivity : FlutterActivity() {
    private val channel = "channel_name"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, channel).setMethodCallHandler { call, result ->
            if (call.method=="sendSMS"){
                val customerPhone = call.argument<String>("phone")
                val customerMessage = call.argument<String>("message")
                if (customerPhone != null && customerMessage != null) {
                    sendSMS(customerPhone, customerMessage, result)
                } else {
                    result.error("INVALID_ARGUMENT", "Phone number or message is null", null)
                }
            }
            else {
                result.notImplemented()
            }
        }
    }

    private fun sendSMS(phone: String, message: String, result: Result) {
        return try {
            val smsManager: SmsManager = SmsManager.getDefault()
            smsManager.sendTextMessage(phone, null, message, null, null)
            result.success("SMS sent successfully")
        } catch (e: Exception) {
            result.error("SMS_SEND_FAILED", "Failed to send SMS: ${e.message}", null)
        }
    }
}

AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.USE_EXACT_ALARM" />
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <application
        android:label="muteify"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:taskAffinity=""
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <receiver android:name="me.sodipto.phone_state_background.PhoneStateBackgroundServiceReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
    <!-- Required to query activities that can process text, see:
         https://developer.android.com/training/package-visibility and
         https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.

         In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
    <queries>
        <intent>
            <action android:name="android.intent.action.PROCESS_TEXT"/>
            <data android:mimeType="text/plain"/>
        </intent>
    </queries>
</manifest>

我尝试过的:

  • 运行
    flutter clean
    并重建 APK。
  • 验证 Flutter 和 Android 代码之间的
    channel_name
    是否匹配。
  • 检查
    MethodChannel
    是否设置在
    configureFlutterEngine
    内部。
  • 在多个设备上测试,仍然面临相同的错误。

预期行为:

即使应用程序在后台运行,应用程序也应该通过

MethodChannel
成功发送短信,而不会抛出
MissingPluginException
错误。

颤医生:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.24.3, on Pop!_OS 22.04 LTS
    6.9.3-76060903-generic, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 2024.1)
[✓] VS Code (version 1.93.1)
[✓] Connected device (3 available)
[✓] Network resources

• No issues found!

问题:

这可能是什么原因造成的

MissingPluginException
我该如何解决?我在方法通道配置或清单设置中遗漏了什么吗?

android flutter sms background-service flutter-method-channel
1个回答
0
投票

您需要在 kotlin 中的 == 运算符内部使用 .equals 这是基本编程,所以我想深入了解它,有很多解释何时使用 == 或 .equals。

if (call.method.equals("sendSMS")){
            val customerPhone = call.argument<String>("phone")
            val customerMessage = call.argument<String>("message")
            if (customerPhone != null && customerMessage != null) {
                sendSMS(customerPhone, customerMessage, result)
            } else {
                result.error("INVALID_ARGUMENT", "Phone number or message is null", null)
            }
        }
        else {
            result.notImplemented()
        }
© www.soinside.com 2019 - 2024. All rights reserved.