Flutter短信验证码自动填充插件sms_otp_autofill的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter短信验证码自动填充插件sms_otp_autofill的使用

简介

sms_otp_autofill 是一个Flutter插件,用于在Android设备上提供SMS OTP(一次性密码)自动填充功能。该插件支持Android 10到14版本。对于iOS,系统默认提供了SMS自动填充功能,因此不需要此插件。

使用方法

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 sms_otp_autofill 依赖:

dependencies:
  sms_otp_autofill: ^latest_version
2. 配置Android项目
2.1 修改 AndroidManifest.xml

android/app/src/main/AndroidManifest.xml 文件中添加以下权限和广播接收器配置:

<uses-permission android:name="android.permission.RECEIVE_SMS"/>

<application>
    <receiver android:name="com.shounakmulay.telephony.sms.IncomingSmsReceiver"
              android:permission="android.permission.BROADCAST_SMS" android:exported="true">
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
        </intent-filter>
    </receiver>
</application>
2.2 修改 build.gradle

android/app/build.gradle 文件中设置 minSdkVersion 为23或更高:

defaultConfig {
    minSdkVersion 23
}
3. 实现短信监听

在发送手机号码给后端之前,需要告诉插件开始监听带有OTP的短信。可以通过调用 telephony.listenIncomingSms 方法来实现:

import 'package:sms_otp_autofill/sms_otp_autofill.dart';

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

  [@override](/user/override)
  State<OtpReceiverView> createState() => _OtpReceiverViewState();
}

class _OtpReceiverViewState extends State<OtpReceiverView> {
  String? otpcode;

  [@override](/user/override)
  void initState() {
    super.initState();
    // 开始监听短信
    telephony.listenIncomingSms(
      onNewMessage: (SmsMessage message) {
        print('Sender: ${message.address}');
        print('Message: ${message.body}');

        String sms = message.body.toString();
        String appName = "SMS_Autofill"; // 替换为你的应用名称

        if (message.body!.contains(appName)) {
          // 提取OTP代码
          otpcode = sms.replaceAll(RegExp(r'[^0-9]'), '');
          setState(() {});
        } else {
          print("Error: SMS does not contain the expected app name");
        }
      },
      listenInBackground: false,
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SMS OTP Auto Fill Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('Received OTP:'),
            Text(
              otpcode ?? 'Waiting for OTP...',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
    );
  }
}
4. Android短信格式约束

为了确保短信能够被正确接收并解析,短信内容需要遵循以下规则:

  • 短信长度不能超过140字节。
  • 短信中必须包含一个一次性代码,该代码将由客户端发送回服务器以完成验证流程。

例如,一条符合要求的短信可以是:

AppName: Your code is 123456

完整示例Demo

以下是一个完整的示例项目,展示了如何使用 sms_otp_autofill 插件来实现短信验证码自动填充功能。

import 'package:flutter/material.dart';
import 'package:sms_otp_autofill/sms_otp_autofill.dart';

void main() {
  runApp(const MyApp());
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SMS OTP Auto Fill Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const OtpReceiverView(),
    );
  }
}

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

  [@override](/user/override)
  State<OtpReceiverView> createState() => _OtpReceiverViewState();
}

class _OtpReceiverViewState extends State<OtpReceiverView> {
  String? otpcode;

  [@override](/user/override)
  void initState() {
    super.initState();
    // 开始监听短信
    telephony.listenIncomingSms(
      onNewMessage: (SmsMessage message) {
        print('Sender: ${message.address}');
        print('Message: ${message.body}');

        String sms = message.body.toString();
        String appName = "SMS_Autofill"; // 替换为你的应用名称

        if (message.body!.contains(appName)) {
          // 提取OTP代码
          otpcode = sms.replaceAll(RegExp(r'[^0-9]'), '');
          setState(() {});
        } else {
          print("Error: SMS does not contain the expected app name");
        }
      },
      listenInBackground: false,
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SMS OTP Auto Fill Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('Received OTP:'),
            Text(
              otpcode ?? 'Waiting for OTP...',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter短信验证码自动填充插件sms_otp_autofill的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter短信验证码自动填充插件sms_otp_autofill的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用sms_otp_autofill插件来实现短信验证码自动填充的示例代码。这个插件可以帮助你更方便地从收到的短信中自动提取并填充验证码。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加sms_otp_autofill依赖:

dependencies:
  flutter:
    sdk: flutter
  sms_otp_autofill: ^2.0.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

2. 配置Android

由于短信读取功能通常涉及到Android的权限管理,你需要在AndroidManifest.xml中添加必要的权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <!-- 其他配置 -->

    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <uses-permission android:name="android.permission.READ_SMS"/>
    <application
        android:label="yourapp"
        android:icon="@mipmap/ic_launcher">
        
        <!-- 注册短信监听服务 -->
        <receiver android:name="com.google.android.gms.auth.api.phone.SmsRetrieverApi$SmsRetrieverReceiver"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS">
            <intent-filter>
                <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVER_ACTION" />
            </intent-filter>
        </receiver>
        
        <!-- 其他配置 -->

    </application>
</manifest>

3. 实现短信验证码自动填充

在你的Flutter代码中,你可以这样使用sms_otp_autofill插件:

import 'package:flutter/material.dart';
import 'package:sms_otp_autofill/sms_otp_autofill.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SMS OTP Autofill Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('SMS OTP Autofill Demo'),
        ),
        body: OTPScreen(),
      ),
    );
  }
}

class OTPScreen extends StatefulWidget {
  @override
  _OTPScreenState createState() => _OTPScreenState();
}

class _OTPScreenState extends State<OTPScreen> {
  final TextEditingController _controller = TextEditingController();
  String? _otp;

  @override
  void initState() {
    super.initState();
    SmsRetriever.startSmsListener().then((registrationId) {
      print("SMS Retriever registrationId: $registrationId");
      // 通常你会将这个registrationId发送到你的服务器进行验证
    }).catchError((e) {
      print("Error starting SMS listener: $e");
    });

    SmsRetriever.addSmsListener((SmsMessage message) {
      final RegExp regex = RegExp(r'\d{6}'); // 假设验证码是6位数字
      final Match? match = regex.firstMatch(message.body!);
      if (match != null) {
        setState(() {
          _otp = match[0]!;
          _controller.text = _otp!;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          TextField(
            controller: _controller,
            keyboardType: TextInputType.number,
            decoration: InputDecoration(
              labelText: 'Enter OTP',
              suffixIcon: IconButton(
                icon: Icon(Icons.clear),
                onPressed: () {
                  _controller.clear();
                },
              ),
            ),
          ),
          SizedBox(height: 20),
          Text(
            'Extracted OTP: $_otp',
            style: TextStyle(color: Colors.grey),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    SmsRetriever.stopSmsListener();
    super.dispose();
  }
}

注意事项

  1. 权限处理:在实际应用中,你需要在运行时请求READ_SMS权限,特别是在Android 6.0及以上版本。
  2. 安全性:短信验证码自动填充虽然方便,但也需要注意安全性,确保你的应用不会滥用此功能。
  3. 依赖版本:确保你使用的sms_otp_autofill插件版本与Flutter SDK兼容。

这段代码展示了如何使用sms_otp_autofill插件来监听并自动填充短信中的验证码。你可以根据自己的需求进一步定制和优化。

回到顶部