Flutter短信自动填充插件flutter_sms_autofill的使用
Flutter短信自动填充插件flutter_sms_autofill的使用
Flutter插件用于提供短信验证码自动填充支持。
对于iOS设备,短信自动填充功能是默认提供的,但对于Android设备,该插件非常有用。由于使用了SMSRetriever API,因此无需请求用户授权读取短信权限。
使用方法
您可以使用两个小部件来自动填充短信验证码:PinFieldAutoFill 和 TextFieldPinAutoFill。
在向后端发送手机号码之前,您需要告知插件监听包含验证码的短信。
为此,您需要执行以下操作:
await SmsAutoFill().listenForCode;
这将在5分钟内监听包含验证码的短信,接收到短信后将自动填充相应的组件。
PinFieldAutoFill
PinFieldAutoFill(
decoration: // 可以选择UnderlineDecoration, BoxLooseDecoration或BoxTightDecoration,更多信息请访问https://github.com/TinoGuo/pin_input_text_field
currentCode: // 预填充验证码
onCodeSubmitted: // 点击提交按钮时的回调
onCodeChanged: // 验证码改变时的回调
codeLength: // 验证码长度,默认为6
)
TextFieldPinAutoFill
TextFieldPinAutoFill(
decoration: // 基本的InputDecoration
currentCode: // 预填充验证码
onCodeSubmitted: // 点击提交按钮时的回调
onCodeChanged: // 验证码改变时的回调
codeLength: // 验证码长度,默认为6
)
Android短信约束
为了使验证码能够被接收,短信必须遵循以下规则(详情请参阅:Google Identity SMS Retriever 文档):
- 长度不得超过140字节
- 包含一次性验证码,客户端将其发送回服务器以完成验证流程
- 结尾必须有11个字符的哈希字符串以标识您的应用
例如:
ExampleApp: 您的验证码是123456
FA+9qCX9VSu
辅助功能
PhoneFieldHint [仅限Android]
PhoneFieldHint 是一个允许用户输入系统电话号码的小部件,并且如果用户选择了电话号码,会自动填充该小部件。
PhoneFieldHint()
自定义CodeAutoFill
如果您想要创建一个可以自动填充短信验证码的自定义组件,可以使用CodeAutoFill混合类,它提供了以下功能:
listenForCode()
:在接收到短信时监听验证码,需要在initState
中调用。cancel()
:取消监听验证码,需要在dispose
中调用。codeUpdated()
:当验证码接收时被调用,可以通过code
字段获取值。unregisterListener()
:注销广播接收器,需要在dispose
中调用。
应用签名
要在运行时获取应用签名,只需调用SmsAutoFill
上的getAppSignature
属性。示例代码可以在示例应用中找到。
示例代码
import 'package:flutter/material.dart';
import 'package:flutter_sms_autofill/flutter_sms_autofill.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
[@override](/user/override)
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String _code = "";
String signature = "{{ app signature }}";
[@override](/user/override)
void initState() {
super.initState();
}
[@override](/user/override)
void dispose() {
SmsAutoFill().unregisterListener();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
home: Scaffold(
appBar: AppBar(
title: const Text('插件示例应用'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
PhoneFieldHint(),
Spacer(),
PinFieldAutoFill(
decoration: UnderlineDecoration(
textStyle: TextStyle(fontSize: 20, color: Colors.black),
colorBuilder: FixedColorBuilder(Colors.black.withOpacity(0.3)),
),
currentCode: _code,
onCodeSubmitted: (code) {},
onCodeChanged: (code) {
if (code!.length == 6) {
FocusScope.of(context).requestFocus(FocusNode());
}
},
),
Spacer(),
TextFieldPinAutoFill(
currentCode: _code,
),
Spacer(),
ElevatedButton(
child: Text('监听短信验证码'),
onPressed: () async {
await SmsAutoFill().listenForCode;
},
),
ElevatedButton(
child: Text('设置验证码为123456'),
onPressed: () async {
setState(() {
_code = '123456';
});
},
),
SizedBox(height: 8.0),
Divider(height: 1.0),
SizedBox(height: 4.0),
Text("应用签名: $signature"),
SizedBox(height: 4.0),
ElevatedButton(
child: Text('获取应用签名'),
onPressed: () async {
signature = await SmsAutoFill().getAppSignature;
setState(() {});
},
),
ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CodeAutoFillTestPage()));
},
child: Text("测试CodeAutoFill混合类"),
)
],
),
),
),
);
}
}
class CodeAutoFillTestPage extends StatefulWidget {
[@override](/user/override)
_CodeAutoFillTestPageState createState() => _CodeAutoFillTestPageState();
}
class _CodeAutoFillTestPageState extends State<CodeAutoFillTestPage> with CodeAutoFill {
String? appSignature;
String? otpCode;
[@override](/user/override)
void codeUpdated() {
setState(() {
otpCode = code!;
});
}
[@override](/user/override)
void initState() {
super.initState();
listenForCode();
SmsAutoFill().getAppSignature.then((signature) {
setState(() {
appSignature = signature;
});
});
}
[@override](/user/override)
void dispose() {
super.dispose();
cancel();
}
[@override](/user/override)
Widget build(BuildContext context) {
final textStyle = TextStyle(fontSize: 18);
return Scaffold(
appBar: AppBar(
title: Text("监听验证码"),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(32, 32, 32, 0),
child: Text(
"当前应用签名: $appSignature",
),
),
const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 32),
child: Builder(
builder: (_) {
if (otpCode == null) {
return Text("正在监听验证码...", style: textStyle);
}
return Text("验证码已接收: $otpCode", style: textStyle);
},
),
),
const Spacer(),
],
),
);
}
}
更多关于Flutter短信自动填充插件flutter_sms_autofill的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter短信自动填充插件flutter_sms_autofill的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 flutter_sms_autofill
插件在 Flutter 应用中实现短信自动填充的示例代码。这个插件允许你的应用监听和读取收到的短信内容,并在适当的表单字段中自动填充验证码(如 OTP)。
1. 添加依赖
首先,在你的 pubspec.yaml
文件中添加 flutter_sms_autofill
依赖:
dependencies:
flutter:
sdk: flutter
flutter_sms_autofill: ^2.0.0 # 请检查最新版本号
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 文件中导入插件:
import 'package:flutter_sms_autofill/flutter_sms_autofill.dart';
3. 请求短信监听权限
在应用启动时请求短信监听权限。注意,这需要在 AndroidManifest.xml 中声明必要的权限,并且在运行时请求这些权限(针对 Android 6.0 及以上版本)。
在 AndroidManifest.xml
中添加权限:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
在 Dart 代码中请求权限(仅 Android):
import 'package:permission_handler/permission_handler.dart';
Future<void> requestSmsPermissions() async {
var status = await Permission.sms.status;
if (!status.isGranted) {
var result = await Permission.sms.request();
if (result.isGranted) {
print("SMS permission granted");
} else {
print("SMS permission denied");
}
} else {
print("SMS permission already granted");
}
}
4. 设置短信监听器
在你的主页面或需要监听短信的地方设置短信监听器:
class _MyAppState extends State<MyApp> {
final TextEditingController _controller = TextEditingController();
@override
void initState() {
super.initState();
// 请求短信权限
requestSmsPermissions();
// 设置短信监听器
FlutterSmsAutofill()
..addSmsListener((SmsMessage message) {
// 假设短信内容是 OTP
RegExp regExp = RegExp(r'\d{6}'); // 假设 OTP 是 6 位数
Iterable<Match> matches = regExp.allMatches(message.body);
if (matches.isNotEmpty) {
String otp = matches.first.group(0)!;
_controller.value = _controller.value.copyWith(text: otp);
}
})
..startListening();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter SMS Autofill Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: _controller,
decoration: InputDecoration(
labelText: 'Enter OTP',
),
keyboardType: TextInputType.number,
),
],
),
),
);
}
@override
void dispose() {
// 停止监听短信
FlutterSmsAutofill().stopListening();
super.dispose();
}
}
5. 完整示例
将上述代码片段整合到一个完整的 Flutter 应用中:
import 'package:flutter/material.dart';
import 'package:flutter_sms_autofill/flutter_sms_autofill.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final TextEditingController _controller = TextEditingController();
@override
void initState() {
super.initState();
requestSmsPermissions();
FlutterSmsAutofill()
..addSmsListener((SmsMessage message) {
RegExp regExp = RegExp(r'\d{6}'); // 假设 OTP 是 6 位数
Iterable<Match> matches = regExp.allMatches(message.body);
if (matches.isNotEmpty) {
String otp = matches.first.group(0)!;
_controller.value = _controller.value.copyWith(text: otp);
}
})
..startListening();
}
Future<void> requestSmsPermissions() async {
var status = await Permission.sms.status;
if (!status.isGranted) {
var result = await Permission.sms.request();
if (!result.isGranted) {
// 处理权限被拒绝的情况
}
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter SMS Autofill Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: _controller,
decoration: InputDecoration(
labelText: 'Enter OTP',
),
keyboardType: TextInputType.number,
),
],
),
),
),
);
}
@override
void dispose() {
FlutterSmsAutofill().stopListening();
_controller.dispose();
super.dispose();
}
}
这段代码展示了如何使用 flutter_sms_autofill
插件来监听短信并在接收到 OTP 时自动填充到 TextField 中。注意,实际使用中可能需要根据具体需求调整正则表达式和权限请求逻辑。