Kha*_*med 18 autofill one-time-password dart flutter
我想自动捕获或读取短信的 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),
),
],
),
)
);
}
}
Run Code Online (Sandbox Code Playgroud)
这是测试短信:12345 is your code to log in.
oneTimeCode 的 Flutter 文档: https://api.flutter.dev/flutter/services/AutofillHints/oneTimeCode-constant.html
iOS: https: //developer.apple.com/documentation/uikit/uitextcontenttype
安卓: https://developer.android.com/reference/androidx/autofill/HintConstants#AUTOFILL_HINT_SMS_OTP
Md.*_*min 27
新答案(截至 23 年 6 月): 我们将使用此包自动填充 sms otp: https: //pub.dev/packages/sms_autofill。将其添加到您的 pubspec.yaml 中。首先,确保您在 Android 手机中收到的短信应在短信开头包含“<#>”,并在短信末尾包含您的应用程序签名密钥。短信示例应如下所示:
<#> 您的 otp 代码是 543216 app_signature。
生成应用程序签名密钥的方法有多种,您还可以使用 sms_autofill 包使用以下代码获取应用程序签名密钥:
await SmsAutoFill().getAppSignature;
Run Code Online (Sandbox Code Playgroud)
它将以字符串格式返回您的应用程序签名,只需将其添加到短信末尾即可。如果您已经拥有应用程序签名,则可以删除上述代码或忽略它。
首先让我们绘制小部件:
PinFieldAutoFill(
decoration: BoxLooseDecoration(
strokeColorBuilder: PinListenColorBuilder(Colors.black, Colors.black26),
bgColorBuilder: const FixedColorBuilder(Colors.white),
strokeWidth: 2,
),
autoFocus: true,
cursor: Cursor(color: Colors.red, enabled: true, width: 1),
currentCode: '',
onCodeSubmitted: (code) {},
codeLength: 6,
onCodeChanged: (code) {
print(code);
},
),
Run Code Online (Sandbox Code Playgroud)
然后在 onInit() 状态下监听短信代码:
await SmsAutoFill().listenForCode();
Run Code Online (Sandbox Code Playgroud)
这将在 5 分钟内监听带有代码的短信,收到后自动填充上述小部件。
在你的 onDispose 方法中不要忘记释放监听器:
SmsAutoFill().unregisterListener();
Run Code Online (Sandbox Code Playgroud)
旧答案: 如果有人想阅读用户的短信,可以使用此答案。此外,如果您使用底部实现,如果您没有提供有关为什么要阅读用户短信的正确解释,PlayStore 可能会拒绝您的应用程序。我希望对于仍在寻找这个问题答案的人们来说还不算太晚。我使用了两个包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';
Run Code Online (Sandbox Code Playgroud)
在您的 AppState 扩展 State 后,放置以下函数来抓取传入的短信:
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.
});
}
Run Code Online (Sandbox Code Playgroud)
我的传入 OTP 消息格式如下所示: 您的手机验证码是 625742。 在上面的函数中,它正在侦听传入的短信并将其保存到字符串中。收到短信后,我将“625742”代码设置到我的文本编辑控制器,方法是在字符串中提供代码的索引位置,然后将该值设置到我的 PinFields(稍后您将看到)。
在 initState 中调用函数:
@override
void initState() {
super.initState();
textEditingController1 = TextEditingController();
initSmsListener();
}
Run Code Online (Sandbox Code Playgroud)
您应该在 dispose 函数中处置任何不使用的内容:
@override
void dispose() {
textEditingController1.dispose();
AltSmsAutofill().unregisterListener();
super.dispose();
}
Run Code Online (Sandbox Code Playgroud)
然后,您需要将 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');
});
},
),
Run Code Online (Sandbox Code Playgroud)
确保将控制器设置为 pinfield 小部件,并在收到短信后使用字符串索引将代码设置为文本字段。例如,请参见下图。

您可以使用此包: https: //pub.dev/packages/sms_autofill
但请考虑以下限制:
Android SMS 约束 对于要接收的代码,需要遵循此处描述的一些规则: https: //developers.google.com/identity/sms-retriever/verify
不超过 140 个字节 以前缀 <#> 开头 包含客户端发送回服务器以完成验证流程的一次性代码 以标识您的应用程序的 11 个字符的哈希字符串结尾 SMS 的一个示例是:
<#> 示例应用程序:您的代码是 123456 FA+9qCX9VSu
| 归档时间: |
|
| 查看次数: |
41542 次 |
| 最近记录: |