我正在使用一个不同的插件来获取用户数据、联系人、照片和相机.当用户单击"不允许"时,应用程序会静默. 我想在用户选中"永不再问"和"不允许"并再次进入应用程序时,向用户显示"询问权限"对话框.

目前,当用户判断不允许时,应用程序不会再次请求

我知道用户必须授予应用程序访问个人信息的权限,包括current locationcameracalendarcontactsmediaLibrarymicrophonesensorsspeech和照片.虽然人们欣赏使用可以访问这些信息的应用程序的便利性,但他们也希望能够控制自己的私有数据.例如,人们喜欢能够自动标记照片的物理位置或查找附近的朋友,但他们也希望 Select 禁用这些功能.

如何在Flutter 中再次请求用户许可?

推荐答案

在应用了几个解决方案后,我发现这个问题非常棘手.所以我想和大家分享,这就是为什么我问了这个问题,我回答了

在大多数操作系统上,权限不仅仅在安装时授予应用程序.相反,开发人员必须在应用程序运行时向用户询问权限.

处理权限的最佳方法是使用permission_handler

我们还可以打开设备的应用程序设置,以便用户可以授予权限. 在Android上,我们可以展示请求权限的理由.

  1. 将此代码添加到软件包的pubspec.yaml文件中:

    dependencies:
      permission_handler: ^5.0.1+1
    
  2. 现在,在您的DART代码中,您可以使用:

    import 'package:permission_handler/permission_handler.dart';
    
  3. 在运行时请求权限时,您仍然需要告诉操作系统您的应用可能会使用哪些权限.这需要向Android和iOS特定文件添加权限配置.

    iOS

    • 为你的信息添加权限.plist文件.Here是一个例子.列出所有可能权限的完整列表.

    IMPORTANT:当你想提交应用程序时,你必须包括所有权限选项.这是因为permission_handler插件涉及所有不同的SDK,而且静态代码分析器(在提交应用程序时由苹果运行)会检测到这一点,如果在Info.plist中找不到匹配的权限选项,就会断言.有关这方面的更多信息,请访问here.

  1. 将以下内容添加到您的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)',
    
                   ## dart: PermissionGroup.calendar
                   'PERMISSION_EVENTS=0',
    
                   ## dart: PermissionGroup.reminders
                   'PERMISSION_REMINDERS=0',
    
                   ## dart: PermissionGroup.contacts
                   # 'PERMISSION_CONTACTS=0',
    
                   ## dart: PermissionGroup.camera
                   # 'PERMISSION_CAMERA=0',
    
                   ## dart: PermissionGroup.microphone
                   # 'PERMISSION_MICROPHONE=0',
    
                   ## dart: PermissionGroup.speech
                   'PERMISSION_SPEECH_RECOGNIZER=0',
    
                   ## dart: PermissionGroup.photos
                   # 'PERMISSION_PHOTOS=0',
    
                   ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
                   'PERMISSION_LOCATION=0',
    
                   ## dart: PermissionGroup.notification
                   # 'PERMISSION_NOTIFICATIONS=0',
    
                   ## dart: PermissionGroup.mediaLibrary
                   'PERMISSION_MEDIA_LIBRARY=0',
    
                   ## dart: PermissionGroup.sensors
                   'PERMISSION_SENSORS=0'
                 ]
        end
      end
    end
    
  2. 删除要使用的权限前面的#个字符.例如,如果您确实需要访问日历,请确保代码如下所示:

    ## dart: PermissionGroup.calendar
    'PERMISSION_EVENTS=0',
    

Android

  1. 将以下内容添加到"gradle.properties"文件中:

    android.useAndroidX=true
    android.enableJetifier=true
    
  2. 一定要把你的"android/app/build.gradle"文件中的前compileSdkVersion位设为28:

     android {
       compileSdkVersion 30
       ...
     }
    
  3. 确保你更换了所有的安卓系统.与AndroidX对应项的依赖关系(完整列表可在此处找到:https://developer.android.com/jetpack/androidx/migrate)

    向您的AndroidManifest.xml%文件添加权限.有Adebug、Amain和Aprofile三个版本,根据你启动应用的方式而定.一般说来,只需在main后版本中添加权限就足够了.下面是一个AndroidManifest.xml版本的示例,其中包含所有可能的权限的完整列表.

Finally you can use like this

Permissions个.你可以得到Permission分的status分,也就是granted分、denied分、restricted分或permanentlyDenied分.

    var status = await Permission.photos.status;

    if (status.isDenied) {
      // We didn't ask for permission yet.
    }

    // You can can also directly ask the permission about its status.
    if (await Permission.location.isRestricted) {
       // The OS restricts access, for example because of parental controls.
    }

Call `request()` on a `Permission` to request it. If it has already been granted before, nothing happens.

request()返回Permission的新状态.

    if (await Permission.contacts.request().isGranted) {
      // Either the permission was already granted before or the user just granted it.
    }

    // You can request multiple permissions at once.
    Map<Permission, PermissionStatus> statuses = await [
      Permission.location,
      Permission.storage,
    ].request();
    print(statuses[Permission.location]);

On Android, you can show a rationale for using permission:

    bool isShown = await Permission.contacts.shouldShowRequestRationale;

Full Example

Container(
  child: Wrap(
    children: <Widget>[
      ListTile(
          leading: Icon(Icons.camera_enhance),
          title: Text(getTranslated(context, "Camera")),
          onTap: () async {
            var status = await Permission.photos.status;
            if (status.isGranted) {
              final pickedFile =
                  await _picker.getImage(source: ImageSource.camera);
              final File file = File(pickedFile.path);
              imageSelected(file);
            } else if (status.isDenied) {
              final pickedFile =
                  await _picker.getImage(source: ImageSource.camera);
              final File file = File(pickedFile.path);
              imageSelected(file);
            } else {
              showDialog(
                  context: context,
                  builder: (BuildContext context) => CupertinoAlertDialog(
                        title: Text('Camera Permission'),
                        content: Text(
                            'This app needs camera access to take pictures for upload user profile photo'),
                        actions: <Widget>[
                          CupertinoDialogAction(
                            child: Text('Deny'),
                            onPressed: () => Navigator.of(context).pop(),
                          ),
                          CupertinoDialogAction(
                            child: Text('Settings'),
                            onPressed: () => openAppSettings(),
                          ),
                        ],
                      ));
            }
          }),
    ],
  ),
)

enter image description here

Flutter相关问答推荐

Flutter iOS日期 Select 器UI中限制日期范围?

我遇到了一个问题,从showDialogue()调用Navigator.pop()两次导致屏幕空白

所需引用Firebase处不存在任何对象

Flutter -使用最小高度展开

Flutter 动画列表一次构建所有项目,而不是仅构建可见的项目

修复后期变量的抖动皮棉

使用Future函数的容器中未显示图像,但在使用图像小工具时显示

如何从DART中的事件列表中获取即将到来的日期

我想在Flutter中画一个箭头,但我似乎无法填满空间

我怎样才能go 掉这个底部导航栏上的白色背景

ScaffoldMessenger 在等待键下方不起作用

TextField 中的富文本并获取 RenderParagraph

是否可以在 flutter 应用程序中使用 jetpack compose?

如何设置行中项目之间的空格相等?

Flutter:如何在 bottomsheet 中创建一个日期 Select 器,如下图所示

你如何在 Flutter 中组合两个数组?

对话框打开时如何使背景模糊?

如何使用列Flutter 中文本占用的空间来控制svg宽度

Flutter 中的无效日期格式 2022 年 11 月 14 日

如何将图像网络装箱到具有边界半径的容器中