【问题标题】:How to get OTP from SMS - autofill如何从 SMS 中获取 OTP - 自动填充
【发布时间】: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

【问题讨论】:

    标签: flutter dart autofill one-time-password


    【解决方案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_autofillhttps://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 stackoverflow.com/questions/65562773/… 访问此链接了解更多详情
      猜你喜欢
      • 1970-01-01
      • 2023-01-09
      • 2021-11-08
      • 1970-01-01
      • 2018-08-10
      • 2019-08-08
      • 1970-01-01
      • 1970-01-01
      • 2019-08-20
      相关资源
      最近更新 更多