如何从 SMS 中获取 OTP - 自动填充

Posted

技术标签:

【中文标题】如何从 SMS 中获取 OTP - 自动填充【英文标题】:How to get OTP from SMS - autofill 【发布时间】:2021-04-10 00:57:42 【问题描述】:

我想自动捕获或读取 SMS 消息的 OTP。我做了一些类似这段代码的测试:

import 'package:flutter/material.dart';

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Demo Auto OTP'),
    );
  


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key, this.title) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();


class _MyHomePageState extends State<MyHomePage> 
  TextEditingController _textController = TextEditingController();
  String _error;

  @override
  Widget build(BuildContext context) 
    return Scaffold(
        appBar: AppBar(
          title: Text("Multi-Factor-Authentication"),
        ),
        body: Form(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                controller: _textController,
                autofillHints: [ AutofillHints.oneTimeCode ],
                keyboardType: TextInputType.visiblePassword,
                maxLength: 6,
                maxLengthEnforced: true,
                style: TextStyle(fontSize: 32),
              ),

              RaisedButton(
                child: Text("Verify"),
                onPressed: () => Navigator.of(context).pop(_textController.value.text),
              ),
            ],
          ),
        )
    );
  

这是测试短信:12345 is your code to log in.

oneTimeCode 的 Flutter 文档: https://api.flutter.dev/flutter/services/AutofillHints/oneTimeCode-constant.html

颤振自动填充:https://github.com/flutter/flutter/blob/7891006299/packages/flutter/lib/src/services/autofill.dart#L362

ios:https://developer.apple.com/documentation/uikit/uitextcontenttype

安卓: https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_SMS_OTP

【问题讨论】:

【参考方案1】:

你可以使用这个包:https://pub.dev/packages/sms_autofill

但请考虑以下限制:

Android SMS 约束 要接收的代码,需要遵循 此处描述的一些规则: https://developers.google.com/identity/sms-retriever/verify

不超过140字节以前缀开头包含一个 客户端发送回您的服务器以完成的一次性代码 验证流程以 11 个字符的哈希字符串结尾 识别您的应用 SMS 的一个示例是:

ExampleApp: 你的代码是 123456 FA+9qCX9VSu

【讨论】:

是的,支持 iOS 并且比 Android 更简单,检查包。【参考方案2】:

对于仍在寻找这个问题的答案的人,我希望我不会迟到。我使用了两个包https://pub.dev/packages/alt_sms_autofill 和https://pub.dev/packages/pin_code_fields。将这两个包添加到您的 pubspec.yaml 文件中。运行“flutter pub get”下载包。

在您的 otp 屏幕中导入两个包:

import 'package:alt_sms_autofill/alt_sms_autofill.dart';
import 'package:pin_code_fields/pin_code_fields.dart';

在您的 AppState 扩展 State 之后,放置以下函数来抓取传入的 SMS:

  TextEditingController textEditingController1;

  String _comingSms = 'Unknown';

  Future<void> initSmsListener() async 

    String comingSms;
    try 
      comingSms = await AltSmsAutofill().listenForSms;
     on PlatformException 
      comingSms = 'Failed to get Sms.';
    
    if (!mounted) return;
    setState(() 
      _comingSms = comingSms;
      print("====>Message: $_comingSms");
      print("$_comingSms[32]");
      textEditingController1.text = _comingSms[32] + _comingSms[33] + _comingSms[34] + _comingSms[35]
          + _comingSms[36] + _comingSms[37]; //used to set the code in the message to a string and setting it to a textcontroller. message length is 38. so my code is in string index 32-37.
    );
  

我收到的 OTP 消息格式如下所示: 您的手机验证码是 625742。 在上面的函数中,它正在监听传入的短信并将其保存到一个字符串中。收到短信后,我将“625742”代码设置到我的 textEditing 控制器,方法是提供代码在字符串中的索引位置,然后将值设置为我的 PinFields,您将在稍后看到。

在您的 initState 中调用函数:

  @override
  void initState() 
    super.initState();
    textEditingController1 = TextEditingController();
    initSmsListener();
  

你应该在你的 dispose 函数中处理你不使用的任何东西:

  @override
  void dispose() 
    textEditingController1.dispose();
    AltSmsAutofill().unregisterListener();
    super.dispose();
  

然后你需要将 pinfields 放在你的构建函数中或这样的列中:

PinCodeTextField(
          appContext: context,
          pastedTextStyle: TextStyle(
            color: Colors.green.shade600,
            fontWeight: FontWeight.bold,
          ),
          length: 6,
          obscureText: false,
          animationType: AnimationType.fade,
          pinTheme: PinTheme(
            shape: PinCodeFieldShape.box,
            borderRadius: BorderRadius.circular(10),
            fieldHeight: 50,
            fieldWidth: 40,
            inactiveFillColor: Colors.white,
            inactiveColor: ColorUtils.greyBorderColor,
            selectedColor: ColorUtils.greyBorderColor,
            selectedFillColor: Colors.white,
            activeFillColor: Colors.white,
            activeColor: ColorUtils.greyBorderColor
          ),
          cursorColor: Colors.black,
          animationDuration: Duration(milliseconds: 300),
          enableActiveFill: true,
          controller: textEditingController1,
          keyboardType: TextInputType.number,
          boxShadows: [
            BoxShadow(
              offset: Offset(0, 1),
              color: Colors.black12,
              blurRadius: 10,
            )
          ],
          onCompleted: (v) 
            //do something or move to next screen when code complete
          ,
          onChanged: (value) 
            print(value);
            setState(() 
              print('$value');
            );
          ,
        ),

确保将控制器设置为 pinfield 小部件,并在收到短信后使用字符串索引将代码设置为文本字段。例如,请参见下图。

【讨论】:

【参考方案3】:

我用这个package 接收短信Check it

它的作用是通过它的监听器监听 SMS,当 SMS 到达时它打印 SMS。

这是Code,我前段时间为此写过(我不确定该软件包是否进行了一些更改或更新,因为我已经有一段时间没有使用它了,但它是在那段时间完美地工作。),

SmsReceiver receiver = new SmsReceiver();
await receiver.onSmsReceived.listen((SmsMessage msg) => checkSMS(msg));

打印SMS正文的方法,

  checkSMS(SmsMessage msg) async 
    print(msg.body);
  

现在您可以自动填充SMS,并使用regexmsg.body 中提取OTP,并将其设置为TextFieldController 文本以进行自动填充。

注意:它将获取每条短信,因此要获取唯一一条您需要的短信,您必须检查关键字或在您身边设置一些正则表达式以仅显示 OTP 消息或消息中的公司名称。

【讨论】:

@khaled09909 它应该自动为 IOS 工作,因为这是 iOS 内置功能。只需自动对焦输入字段,它可能会自动填充。如果我错了,请纠正我。 @khaled09909 ***.com/questions/65562773/… 访问此链接了解更多详情

以上是关于如何从 SMS 中获取 OTP - 自动填充的主要内容,如果未能解决你的问题,请参考以下文章

sms_otp_auto_verify 无法自动检测 OTP

WebView(Android App)中弹出的模态对话框中的自动填充文本字段

浏览器中的自动增量验证短信代码 (otp || 2fa)

Flutter sms_autofill 并不总是自动读取 OTP

自动填充 otp web 视图反应原生 android

如何在反应原生文本输入中自动粘贴在 SMS 中收到的一次性代码