Flutter:iOS 不请求权限

问题描述 投票:0回答:4

我的代码显示了“重试”按钮:

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>
flutter
4个回答

2
投票

根据当前版本的权限处理程序,您需要在

Podfile
plist
两个文件中添加联系人权限,确保您已添加此权限。


0
投票

如果某个权限被永久拒绝,则只能从应用程序设置中启用它(禁止重新安装应用程序)。您可以使用

openAppSettings
功能将用户重定向至设置。


0
投票

要修复 iOS 上始终返回 PermissionStatus.permanentlyDenied 的联系人权限请求:

  1. 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
  1. NSContactsUsageDescription
    添加到
    ios/Runner/Info.plist
<key>NSContactsUsageDescription</key>
<string>This app requires contacts access to display your contacts list</string>
  1. 将依赖项添加到
    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'),
          ),
        ],
      ),
    );
  }
}

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.