You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用sms_advanced调用querySms报MissingPluginException求助

问题解决:sms_advanced插件MissingPluginException异常

异常详情

调用querySms()方法读取短信时,触发以下异常:

Unhandled Exception: MissingPluginException(No implementation found for method getSent on channel plugins.elyudde.com/querySMS)

已确认readSmsMessages()函数已执行,但因异常中断。

解决步骤

  • 清理重建项目
    执行以下命令清理缓存并重新构建,插件未正确链接到原生端是此类异常的常见原因:

    flutter clean
    flutter pub get
    flutter run
    
  • 检查版本兼容性
    查看pubspec.yaml中sms_advanced的版本,确认其与当前Flutter SDK版本兼容。若存在版本不匹配,尝试升级或降级插件后重新执行flutter pub get。

  • 验证原生权限配置

    • Android:确保android/app/src/main/AndroidManifest.xml中添加短信读取权限:
      <uses-permission android:name="android.permission.READ_SMS"/>
      
    • iOS:在ios/Runner/Info.plist中添加短信权限描述:
      <key>NSMessagesUsageDescription</key>
      <string>需要读取短信以追踪交易记录</string>
      
  • 临时替换方法排查问题
    暂时将querySms调用替换为getAllSms,验证是否能正常获取短信:

    // 替换原querySms调用
    final List<SmsMessage> messages = await query.getAllSms;
    

    如果此方法正常运行,说明querySms方法可能存在版本兼容问题,可考虑改用其他方式筛选短信。

  • 重启开发环境
    重启IDE(如Android Studio/VS Code)以及模拟器或真机,清除缓存异常后重新运行项目。

相关代码参考

导入语句

import 'package:expense_tracker/database_helper.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'transaction_screen.dart';
import 'profile_screen.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:sms_advanced/sms_advanced.dart';

MyApp类

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Expense Tracker',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

HomeScreenState类

class _HomeScreenState extends State<HomeScreen> {
  static const platform =
      MethodChannel('com.example.expense_tracker/notifications');

  String _transactionMessage = 'No transactions yet.';
  int _selectedIndex = 0;
  List<Map<String, dynamic>> transactions = [];

  @override
  void initState() {
    super.initState();
    _startNotificationListener();
    requestSmsPermission();
    readSmsMessages();
    fetchAndDisplayTransactions();
  }

  void readSmsMessages() async {
    debugPrint("readSmsMessages called");
    final SmsQuery query = SmsQuery();

    // final List<SmsMessage> messages = await query.getAllSms;

    List<SmsQueryKind> kinds = [SmsQueryKind.Inbox, SmsQueryKind.Sent];
    final List<SmsMessage> messages = await query.querySms(kinds: kinds);

    debugPrint("messages length: ${messages.length}");
    if (messages.isNotEmpty) {
      debugPrint("if");
      for (var message in messages) {
        if (isUpiTransaction(message.body.toString())) {
          // Extract relevant data (amount, transaction ID, etc.)
          setState(() {
            _transactionMessage = message.body.toString();
            storeTransaction(extractTransactionData(_transactionMessage));
            debugPrint(_transactionMessage);
          });
        }
      }
    }
  }

  Map<String, dynamic> extractTransactionData(String messageBody) {
    // Use regex or pattern matching to extract data from message
    RegExp amountPattern = RegExp(r'(\d+(\.\d{1,2})?)');
    RegExp transactionIdPattern = RegExp(r'Transaction ID: (\w+)');

    String? amount = amountPattern.firstMatch(messageBody)?.group(0);
    String? transactionId =
        transactionIdPattern.firstMatch(messageBody)?.group(1);

    return {
      'amount': amount,
      'transactionId': transactionId,
      'message': messageBody,
    };
  }

  bool isUpiTransaction(String messageBody) {
    // Simple keyword check for UPI-related SMS
    return messageBody.contains('credited') || messageBody.contains('debited');
  }

  Future<void> _startNotificationListener() async {
    try {
      await platform.invokeMethod('startNotificationListener');
    } on PlatformException catch (e) {
      debugPrint("e.message: ${e.message}");
    }

    platform.setMethodCallHandler((call) async {
      if (call.method == 'notifyTransaction') {
        String transactionData = call.arguments;
        setState(() {
          _transactionMessage = transactionData;
          debugPrint(_transactionMessage);
        });
      }
    });
  }

  Future<void> requestSmsPermission() async {
    var status = await Permission.sms.status;
    if (!status.isGranted) {
      await Permission.sms.request();
    }
  }

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  void storeTransaction(Map<String, dynamic> transactionData) async {
    await DatabaseHelper.instance.insertTransaction(transactionData);
  }

  Future<List<Map<String, dynamic>>> fetchAndDisplayTransactions() async {
    List<Map<String, dynamic>> dbtransactions =
        await DatabaseHelper.instance.getTransactions();
    transactions = dbtransactions;
    return dbtransactions;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Expense Tracker'),
      ),
      body: IndexedStack(
        index: _selectedIndex,
        children: [
          TransactionScreen(
            transactions: transactions,
          ),
          const ProfileScreen(),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.list),
            label: 'Transactions',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: 'Profile',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.blue,
        onTap: _onItemTapped,
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Shashwat Srivastava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:45:56