diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index a2a967bc..341d6fae 100755 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -29,6 +29,9 @@ + + + diff --git a/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_page.dart b/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_page.dart index 5d6e9d30..c4e62f99 100755 --- a/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_page.dart +++ b/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_page.dart @@ -20,6 +20,7 @@ import 'package:star_lock/tools/pickers/time_picker/model/pduration.dart'; import 'package:star_lock/tools/regularExpression.dart'; import 'package:star_lock/tools/showTipView.dart'; import 'package:star_lock/tools/submitBtn.dart'; +import 'package:permission_handler/permission_handler.dart'; class SendElectronicKeyView extends StatefulWidget { SendElectronicKeyView({required this.type, Key? key}) : super(key: key); @@ -31,6 +32,14 @@ class SendElectronicKeyView extends StatefulWidget { class _SendElectronicKeyViewState extends State with AutomaticKeepAliveClientMixin { + late FlutterContactPicker _contactPicker; + + @override + void initState() { + super.initState(); + _contactPicker = FlutterContactPicker(); + } + @override Widget build(BuildContext context) { super.build(context); @@ -215,45 +224,81 @@ class _SendElectronicKeyViewState extends State alignment: Alignment.center, child: InkWell( onTap: () async { - final Contact? currentContact = - await logic.state.contactPicker.selectContact(); - if (currentContact != null) { - logic.state.contact = currentContact; + try { + final PermissionStatus status = + await Permission.contacts.request(); + if (status.isGranted) { + // 保存当前路由 + final currentRoute = ModalRoute.of(context); - // 处理手机号 - if (currentContact.phoneNumbers != null && - currentContact.phoneNumbers!.isNotEmpty) { - // 获取第一个手机号并清理格式 - String phoneNumber = currentContact.phoneNumbers![0]; - // 移除所有空格、括号、连字符等特殊字符 - phoneNumber = - phoneNumber.replaceAll(RegExp(r'[\s\(\)\-]'), ''); - // 如果号码以+开头,保留+号 - if (phoneNumber.startsWith('+')) { - phoneNumber = '+' + - phoneNumber - .substring(1) - .replaceAll(RegExp(r'[^\d]'), ''); - } else { - phoneNumber = - phoneNumber.replaceAll(RegExp(r'[^\d]'), ''); + final Contact? currentContact = + await _contactPicker.selectContact(); + + // 检查路由是否仍然存在且组件是否挂载 + if (currentRoute?.isCurrent == true && mounted) { + // 检查 GetX 控制器是否仍然存在 + if (Get.isRegistered( + tag: widget.type)) { + final logic = Get.find( + tag: widget.type); + + if (currentContact != null) { + // 处理手机号 + if (currentContact.phoneNumbers != null && + currentContact.phoneNumbers!.isNotEmpty) { + String phoneNumber = + currentContact.phoneNumbers![0]; + // 移除所有空格、括号、连字符等特殊字符 + phoneNumber = phoneNumber.replaceAll( + RegExp(r'[\s\(\)\-]'), ''); + // 如果号码以+开头,保留+号 + if (phoneNumber.startsWith('+')) { + phoneNumber = '+' + + phoneNumber + .substring(1) + .replaceAll(RegExp(r'[^\d]'), ''); + } else { + phoneNumber = phoneNumber.replaceAll( + RegExp(r'[^\d]'), ''); + } + logic.state.emailOrPhoneController.text = + phoneNumber; + logic.state.emailOrPhone.value = phoneNumber; + } + + // 处理姓名 + if (currentContact.fullName != null && + currentContact.fullName!.isNotEmpty) { + logic.state.keyNameController.text = + currentContact.fullName!; + } + + // 更新UI + logic.update(); + } + } } - logic.state.emailOrPhoneController.text = phoneNumber; } else { - logic.state.emailOrPhoneController.text = ''; + // 权限被拒绝,显示提示 + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('需要通讯录权限才能选择联系人'.tr), + duration: const Duration(seconds: 2), + ), + ); + } } - - // 处理姓名 - if (currentContact.fullName != null && - currentContact.fullName!.isNotEmpty) { - logic.state.keyNameController.text = - currentContact.fullName!; - } else { - logic.state.keyNameController.text = ''; + } catch (e) { + print('Error selecting contact: $e'); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('获取通讯录失败,请检查权限设置'.tr), + duration: const Duration(seconds: 2), + ), + ); } - - // 更新UI - logic.update(); } }, ), @@ -639,17 +684,65 @@ class _SendElectronicKeyViewState extends State alignment: Alignment.center, child: InkWell( onTap: () async { - final Contact? currentContact = - await logic.state.contactPicker.selectContact(); - logic.state.contact = currentContact!; - if (currentContact.phoneNumbers!.isNotEmpty) { - logic.state.emailOrPhoneController.text = currentContact - .phoneNumbers![0] - .replaceAll(RegExp(r'\s+\b|\b\s'), ''); - } - if (currentContact.fullName!.isNotEmpty) { - logic.state.keyNameController.text = - currentContact.fullName!; + try { + final PermissionStatus status = + await Permission.contacts.request(); + if (status.isGranted) { + final Contact? currentContact = + await _contactPicker.selectContact(); + if (currentContact != null && mounted) { + // 处理手机号 + if (currentContact.phoneNumbers != null && + currentContact.phoneNumbers!.isNotEmpty) { + String phoneNumber = currentContact.phoneNumbers![0]; + // 移除所有空格、括号、连字符等特殊字符 + phoneNumber = + phoneNumber.replaceAll(RegExp(r'[\s\(\)\-]'), ''); + // 如果号码以+开头,保留+号 + if (phoneNumber.startsWith('+')) { + phoneNumber = '+' + + phoneNumber + .substring(1) + .replaceAll(RegExp(r'[^\d]'), ''); + } else { + phoneNumber = + phoneNumber.replaceAll(RegExp(r'[^\d]'), ''); + } + logic.state.emailOrPhoneController.text = phoneNumber; + logic.state.emailOrPhone.value = phoneNumber; + } + + // 处理姓名 + if (currentContact.fullName != null && + currentContact.fullName!.isNotEmpty) { + logic.state.keyNameController.text = + currentContact.fullName!; + } + + // 更新UI + logic.update(); + } + } else { + // 权限被拒绝,显示提示 + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('需要通讯录权限才能选择联系人'.tr), + duration: const Duration(seconds: 2), + ), + ); + } + } + } catch (e) { + print('Error selecting contact: $e'); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('获取通讯录失败,请检查权限设置'.tr), + duration: const Duration(seconds: 2), + ), + ); + } } }, ), @@ -759,7 +852,7 @@ class _SendElectronicKeyViewState extends State child: Text( '取消'.tr, style: TextStyle( - color: Colors.black, fontSize: ScreenUtil().setSp(24)), + color: Colors.black, fontSize: 24.sp), ), onPressed: () { Navigator.pop(context); @@ -802,7 +895,7 @@ class _SendElectronicKeyViewState extends State Text( titleStr, style: TextStyle( - fontSize: ScreenUtil().setSp(20), color: Colors.black), + fontSize: 20.sp, color: Colors.black), ), ], ), diff --git a/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_state.dart b/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_state.dart index 7ada2123..61121249 100755 --- a/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_state.dart +++ b/lib/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/view/sendElectronicKeyView_state.dart @@ -15,8 +15,8 @@ class SendElectronicKeyViewState { TextEditingController realNameController = TextEditingController(); //真实姓名输入框 TextEditingController idCardController = TextEditingController(); //身份证号输入框 - final FlutterContactPicker contactPicker = FlutterContactPicker(); - late Contact contact; + // final FlutterContactPicker contactPicker = FlutterContactPicker(); + // late Contact contact; RxBool isRemoteUnlock = false.obs; //是否允许远程开锁 RxBool isAuthentication = false.obs; //是否可以实名认证