如何在Flutter中请求和检查权限 1.安卓设置:2. iOS 设置:3.颤振设置:主要工作:完整代码:

问题描述

用户单击“不允许”时,我正在使用各种插件获取用户数据,联系人,照片和相机,该应用程序将保持静音。 我想在用户选中``不再询问并且不允许''并再次进入应用程序时向用户显示``询问权限''对话框。

当前,当用户选中“不允许”时,应用程序再也不会询问

我知道用户必须授予应用访问权限才能访问个人信息,包括当前位置相机日历联系人 mediaLibrary 麦克风传感器语音和照片。尽管人们喜欢使用可以访问此信息的应用程序所带来的便利,但他们也希望能够控制自己的私人数据。例如,人们喜欢能够自动标记其实际位置的照片或找到附近的朋友,但他们也希望选择禁用这些功能

如何再次扑通用户权限?

解决方法

我对此问题感到非常烦恼。应用了几种解决方案后,我发现了该解决方案。所以我想与所有人分享,这就是为什么我问这个问题并回答了

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

处理权限的最佳方法是使用permission_handler 插入。该插件提供了跨平台(iOS,Android)API来请求权限并检查其状态。

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

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

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

    import 'package:permission_handler/permission_handler.dart';
    
  3. 在运行时请求权限的同时,您仍然需要告诉OS您的应用程序可能使用哪些权限。这就需要向Android和iOS专用文件添加权限配置。

    iOS

    • 向您的Info.plist文件添加权限。 Here是一个示例Info.plist,其中包含所有可能的权限的完整列表。

    Android

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

      android.useAndroidX=true
      android.enableJetifier=true
      
    2. 确保将“ compileSdkVersion”文件中的android/app/build.gradle设置为28:

      android {
        compileSdkVersion 28
        ...
      }
      
    3. 确保您替换了所有的android系统。依赖于其AndroidX对应版本(可在此处找到完整列表:https://developer.android.com/jetpack/androidx/migrate)

    为您的AndroidManifest.xml文件添加权限。有debugmainprofile版,具体取决于您启动应用程序的方式。通常,仅向版本main添加权限就足够了。这是一个示例AndroidManifest.xml,其中包含所有可能的权限的完整列表。

  4. 有许多权限。您可以获得Permission的{​​{1}},可以是statusundeterminedgranteddeniedrestricted

    permanentlyDenied

    var status = await Permission.camera.status; if (status.isUndetermined) { // 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. } 上致电request()进行请求。如果以前已授予它,则什么也不会发生。 Permission返回request()的新状态。

    Permission

    在Android上,您可以显示使用权限的原理:

    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]);
    

完整示例

bool isShown = await Permission.contacts.shouldShowRequestRationale;

enter image description here

,

为简单起见,我使用了位置权限。要请求其他权限,只需将位置替换为该权限即可。这是list of all permissions

1.安卓设置:

  1. 将这些添加到 android/grade.properties 文件:

    android.useAndroidX=true
    android.enableJetifier=true
    
  2. android/app/build.gradle 文件中:

    android {
      compileSdkVersion 30 // Set this to at least 30
      ...
    }
    
  3. android/app/src/main/AndroidManifest.xml 文件添加权限

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
      ...
     </manifest>
    

2. iOS 设置:

  1. 将此添加到 info.plist 文件:

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>App needs location permission to work</string>
    
  2. PERMISSION_LOCATION=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)',## Add the following line.
             'PERMISSION_LOCATION=1'
          ]
    
        end
      end
    end
    

3.颤振设置:

将此添加到 pubspec.yaml 文件:

permission_handler: ^8.0.0+2

主要工作:

  • 检查权限:

    检查位置(即 GPS)是否开启。

    final serviceStatus = await Permission.locationWhenInUse.serviceStatus;
    bool isGpsOn = serviceStatus == ServiceStatus.enabled;
    
  • 请求许可:

    final status = await Permission.locationWhenInUse.request();
    if (status == PermissionStatus.granted) {
      print('Permission granted');
    } else if (status == PermissionStatus.denied) {
      print('Denied. Show a dialog with a reason and again ask for the permission.');
    } else if (status == PermissionStatus.permanentlyDenied) {
      print('Take the user to the settings page.');
    }
    

完整代码:

class HomePage extends StatelessWidget {
  Future<void> _checkPermission() async {
    final serviceStatus = await Permission.locationWhenInUse.serviceStatus;
    final isGpsOn = serviceStatus == ServiceStatus.enabled;
    if (!isGpsOn) {
      print('Turn on location services before requesting permission.');
      return;
    }

    final status = await Permission.locationWhenInUse.request();
    if (status == PermissionStatus.granted) {
      print('Permission granted');
    } else if (status == PermissionStatus.denied) {
      print('Permission denied. Show a dialog and again ask for the permission');
    } else if (status == PermissionStatus.permanentlyDenied) {
      print('Take the user to the settings page.');
      await openAppSettings();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: _checkPermission,child: Text('Check Permission'),),);
  }
}
,

我建议使用 permission_handler 库并编写抽象代码(策略模式)以相同的方式处理所有权限。通常,文档是模糊的,并且没有显示如何处理不可恢复/禁用情况。

代码:

/// handles .isLimited for iOS 14+ where we can restrict access.
abstract class GrantPermissionStrategy {
  final Permission permission;

  GrantPermissionStrategy(this.permission);

  Future<void> request({
    required final OnPermatentlyDenied onPermatentlyDenied,required final OnGranted onGranted,}) async {
    PermissionStatus status = await permission.status;
    print("GrantPermissionStrategy status: $status");
    if (status.isPermanentlyDenied) {
      onPermatentlyDenied.call();
      return;
    }
    if (!status.isLimited && !status.isGranted) {
      final PermissionStatus result = await permission.request();
      if (!result.isGranted) {
        return;
      }
    }
    onGranted.call();
  }
}

typedef OnPermatentlyDenied = void Function();

typedef OnGranted = void Function();


而且,你可以做出具体的实现,比如:

class GrantPermissionCameraStrategy extends GrantPermissionStrategy {
  GrantPermissionCameraStrategy() : super(Permission.camera);
}

class GrantPermissionPhotosStrategy extends GrantPermissionStrategy {
  GrantPermissionPhotosStrategy() : super(Platform.isAndroid ? Permission.storage : Permission.photos);
}

最后,调用它!:

    await GrantPermissionPhotosStrategy().request(onPermatentlyDenied: () {
      // launch dialog,make user go to app settings
    },onGranted: () async {
      // we have passed! Launch the feature.
    });
  }