我的代码显示了“重试”按钮:
TextButton(
onPressed: () async {
await _checkPermission().then(
(hasGranted) {
if (hasGranted == PermissionStatus.granted) {
refreshContacts();
}
},
);
},
...
Future<PermissionStatus> _checkPermission() async {
final Permission permission = Permission.contacts;
final status = await permission.request();
return status;
}
这总是返回:
PermissionStatus.permanentlyDenied
但它不会再次打开权限问题。
信息.plist:
<key>NSContactsUsageDescription</key>
<string>This app requires access to display the contacts list. This will be used to import contacts automatically if necessary to the app contacts list.</string>
根据当前版本的权限处理程序,您需要在
Podfile
和 plist
两个文件中添加联系人权限,确保您已添加此权限。
如果某个权限被永久拒绝,则只能从应用程序设置中启用它(禁止重新安装应用程序)。您可以使用
openAppSettings
功能将用户重定向至设置。
要修复 iOS 上始终返回 PermissionStatus.permanentlyDenied 的联系人权限请求:
PERMISSION_CONTACTS=1
添加到ios/Podfile
:post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
'PERMISSION_CONTACTS=1'
]
end
end
end
NSContactsUsageDescription
添加到ios/Runner/Info.plist
:<key>NSContactsUsageDescription</key>
<string>This app requires contacts access to display your contacts list</string>
pubspec.yaml
:dependencies:
permission_handler: 11.3.1
contacts_service: 0.6.3
示例:
import 'package:contacts_service/contacts_service.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp();
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: ContactsScreen(),
);
}
}
class ContactsScreen extends StatefulWidget {
const ContactsScreen();
@override
State<ContactsScreen> createState() => _ContactsScreenState();
}
class _ContactsScreenState extends State<ContactsScreen> {
final List<Contact> _contacts = [];
bool _isLoading = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Contacts'),
),
body: SafeArea(
child: Column(
children: [
ElevatedButton(
onPressed: _isLoading ? null : () => _fetchContacts(),
child: Text(_isLoading ? 'Fetching...' : 'Fetch Contacts'),
),
Expanded(
child: _contacts.isEmpty
? const Center(
child: Text('No contacts'),
)
: ListView.builder(
itemCount: _contacts.length,
itemBuilder: (context, index) {
Contact contact = _contacts[index];
final List<Item>? phones = contact.phones;
return ListTile(
leading: const CircleAvatar(
child: Icon(Icons.person),
),
title: Text(contact.displayName ?? 'No name'),
subtitle: Text(
phones == null || phones.isEmpty
? "No phone number"
: '${phones[0].label ?? ''} ${phones[0].value ?? ''}',
),
);
},
),
),
],
),
),
);
}
Future<void> _fetchContacts() async {
if (_isLoading) {
return;
}
setState(() {
_isLoading = true;
});
try {
final PermissionStatus permissionStatus = await Permission.contacts.request();
if (permissionStatus == PermissionStatus.granted) {
final contacts = await ContactsService.getContacts();
setState(() {
_contacts.clear();
_contacts.addAll(contacts);
});
} else {
_showPermissionDeniedDialog();
}
} on Exception catch (e) {
_showErrorDialog('Error fetching contacts: $e');
} finally {
setState(() {
_isLoading = false;
});
}
}
void _showPermissionDeniedDialog() {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('Permission Required'),
content: const Text(
'Contacts permission is required to fetch contacts. '
'Please enable it in settings.',
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
TextButton(
onPressed: () {
Navigator.pop(context);
openAppSettings();
},
child: const Text('Open Settings'),
),
],
),
);
}
void _showErrorDialog(String message) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('Error'),
content: Text(message),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('OK'),
),
],
),
);
}
}