在没有提前按下任何按钮事件的情况下,如何在获得生物认证结果为真后以编程方式获得页面转换?
How Can I get a page transition programmatically after getting biometric authentication result true without any button press event in advance?
我正在用 flutter 实现的 local_auth 插件创建一个应用程序。
我想要下面的流程。
1.background page(BioAuthScreen) is up
2.simultaneously authenticateWithBiometrics dialog is up.
3.if result is true, get the page transition to HomeScreen(folloing comment // 3),
如果我按下按钮(注释// 4 之后的代码),
它的工作。(向上对话框,如果结果为真,页面转换OK)。
但我不喜欢背景页面中的按钮。
如果我将代码放在注释 // 1 或 // 2 之后,对话框就会打开,如果结果为真,
但背景页面仍然存在。没有错误。
这是代码。
class BioAuthScreen extends StatefulWidget {
BioAuthScreen({Key key, this.initFlag = false}) : super(key: key);
final bool initFlag;
@override
_BioAuthScreenState createState() => _BioAuthScreenState();
}
class _BioAuthScreenState extends State<BioAuthScreen>
with WidgetsBindingObserver {
final LocalAuthentication _localAuthentication = LocalAuthentication();
bool _isAuthenticated;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
// 1
/* WidgetsBinding.instance.addPostFrameCallback((_) async {
await _getAuthenticated();
}); */
}
@override
void didChangeDependencies() async {
super.didChangeDependencies();
await Future.delayed(const Duration(milliseconds: 700));
// 2
// await _getAuthenticated();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.inactive) {
} else if (state == AppLifecycleState.paused) {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => BioAuthScreen()));
} else if (state == AppLifecycleState.resumed) {}
}
Future<List<BiometricType>> _getListOfBiometricTypes() async {
List<BiometricType> listOfBiometrics;
try {
listOfBiometrics = await _localAuthentication.getAvailableBiometrics();
} on PlatformException catch (e) {
print(e);
}
print(listOfBiometrics);
return listOfBiometrics;
}
Future<void> _getAuthenticated() async {
var result = false;
var availableBiometricTypes = await _getListOfBiometricTypes();
try {
if (availableBiometricTypes.contains(BiometricType.face) ||
availableBiometricTypes.contains(BiometricType.fingerprint)) {
result = await _localAuthentication.authenticateWithBiometrics(
localizedReason: '生体認証',
useErrorDialogs: true,
stickyAuth: false,
);
}
} on PlatformException catch (e) {
print(e);
}
if (!mounted) return;
print('result: $result');
// 3
if (result) {
await Navigator.pushNamed(context, Constants.homeScreenRoute);
}
}
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
final screenHeight = MediaQuery.of(context).size.height;
return SafeArea(
child: Scaffold(
body: FractionallySizedBox(
widthFactor: 1,
heightFactor: 1,
child: DecoratedBox(
decoration: const BoxDecoration(
color: CustomColors.midBlue,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const Padding(
padding: EdgeInsets.all(40.0),
),
// Title
AuthTitleComponent(),
SizedBox(height: screenHeight * 0.28),
ButtonTheme(
minWidth:
screenWidth > 600 ? screenWidth * 0.6 : screenWidth * 0.7,
height: 45,
child: RaisedButton(
elevation: 3.0,
color: CustomColors.lightBlue,
// 4
onPressed: () async {
await _getAuthenticated();
},
child: Text(
'BioMetricAuthLogin',
style: Theme.of(context)
.textTheme
.headline2
.copyWith(color: Colors.white),
),
),
),
],
),
),
),
),
);
}
}
我能够使用您提供的代码片段复制报告的行为。当通过 didChangeAppLifecycleState
.
调用生物识别身份验证时,LocalAuthentication.authenticate
捕获 PlatformException
这似乎是一个错误,我已将其作为问题提交 here。我使用的是 Flutter 2.0.0 稳定版和 local_auth 1.1.0 作为参考。
我正在用 flutter 实现的 local_auth 插件创建一个应用程序。 我想要下面的流程。
1.background page(BioAuthScreen) is up
2.simultaneously authenticateWithBiometrics dialog is up.
3.if result is true, get the page transition to HomeScreen(folloing comment // 3),
如果我按下按钮(注释// 4 之后的代码), 它的工作。(向上对话框,如果结果为真,页面转换OK)。 但我不喜欢背景页面中的按钮。 如果我将代码放在注释 // 1 或 // 2 之后,对话框就会打开,如果结果为真, 但背景页面仍然存在。没有错误。
这是代码。
class BioAuthScreen extends StatefulWidget {
BioAuthScreen({Key key, this.initFlag = false}) : super(key: key);
final bool initFlag;
@override
_BioAuthScreenState createState() => _BioAuthScreenState();
}
class _BioAuthScreenState extends State<BioAuthScreen>
with WidgetsBindingObserver {
final LocalAuthentication _localAuthentication = LocalAuthentication();
bool _isAuthenticated;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
// 1
/* WidgetsBinding.instance.addPostFrameCallback((_) async {
await _getAuthenticated();
}); */
}
@override
void didChangeDependencies() async {
super.didChangeDependencies();
await Future.delayed(const Duration(milliseconds: 700));
// 2
// await _getAuthenticated();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.inactive) {
} else if (state == AppLifecycleState.paused) {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => BioAuthScreen()));
} else if (state == AppLifecycleState.resumed) {}
}
Future<List<BiometricType>> _getListOfBiometricTypes() async {
List<BiometricType> listOfBiometrics;
try {
listOfBiometrics = await _localAuthentication.getAvailableBiometrics();
} on PlatformException catch (e) {
print(e);
}
print(listOfBiometrics);
return listOfBiometrics;
}
Future<void> _getAuthenticated() async {
var result = false;
var availableBiometricTypes = await _getListOfBiometricTypes();
try {
if (availableBiometricTypes.contains(BiometricType.face) ||
availableBiometricTypes.contains(BiometricType.fingerprint)) {
result = await _localAuthentication.authenticateWithBiometrics(
localizedReason: '生体認証',
useErrorDialogs: true,
stickyAuth: false,
);
}
} on PlatformException catch (e) {
print(e);
}
if (!mounted) return;
print('result: $result');
// 3
if (result) {
await Navigator.pushNamed(context, Constants.homeScreenRoute);
}
}
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
final screenHeight = MediaQuery.of(context).size.height;
return SafeArea(
child: Scaffold(
body: FractionallySizedBox(
widthFactor: 1,
heightFactor: 1,
child: DecoratedBox(
decoration: const BoxDecoration(
color: CustomColors.midBlue,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const Padding(
padding: EdgeInsets.all(40.0),
),
// Title
AuthTitleComponent(),
SizedBox(height: screenHeight * 0.28),
ButtonTheme(
minWidth:
screenWidth > 600 ? screenWidth * 0.6 : screenWidth * 0.7,
height: 45,
child: RaisedButton(
elevation: 3.0,
color: CustomColors.lightBlue,
// 4
onPressed: () async {
await _getAuthenticated();
},
child: Text(
'BioMetricAuthLogin',
style: Theme.of(context)
.textTheme
.headline2
.copyWith(color: Colors.white),
),
),
),
],
),
),
),
),
);
}
}
我能够使用您提供的代码片段复制报告的行为。当通过 didChangeAppLifecycleState
.
LocalAuthentication.authenticate
捕获 PlatformException
这似乎是一个错误,我已将其作为问题提交 here。我使用的是 Flutter 2.0.0 稳定版和 local_auth 1.1.0 作为参考。