Flutter控件 : permission_handler v9.2.0

用于 Flutter 的权限插件。这个插件提供了一个跨平台(iOS,Android)的API来请求和检查权限。

在大多数操作系统中,权限并不是在安装时授予应用程序的。相反,开发者必须在应用运行时向用户请求权限。

这个插件提供了一个跨平台(iOS、Android)的API来请求权限并检查其状态。你也可以打开设备的应用设置,这样用户就可以授予一个权限。
在Android上,你可以显示请求权限的理由。

设置

虽然权限是在运行时被请求的,但你仍然需要告诉操作系统你的应用程序可能会使用哪些权限。这需要在Android和iOS的特定文件中添加权限配置。

安卓
升级1.12之前的安卓项目

自4.4.0版本以来,该插件使用Flutter 1.12 Android插件API实现。不幸的是,这意味着应用程序开发人员也需要迁移他们的应用程序,以支持新的Android基础设施。你可以按照升级1.12版之前的安卓项目迁移指南来做。如果不这样做,可能会导致意外的行为。最常见的错误是permission_handler在调用权限的.request()方法后没有返回。

AndroidX

从3.1.0版本开始,permission_handler插件切换到AndroidX版本的Android支持库。这意味着你需要确保你的安卓项目也被升级到支持AndroidX。

  1. 在你的 “gradle.properties “文件中添加以下内容。
android.useAndroidX=true
android.enableJetifier=true
  1. 确保你在 “android/app/build.gradle “文件中把compileSdkVersion设置为31
android {
  compileSdkVersion 31
  ...
}
  1. 确保你将所有的android.依赖关系替换为AndroidX的对应关系

在你的AndroidManifest.xml文件中添加权限。有一个debug, main and profile,它们的选择取决于你如何启动你的应用程序。一般来说,只在主版本中添加权限即可。下面是一个AndroidManifest.xml的例子,其中有一个所有可能的权限的完整列表。

iOS
在你的Info.plist文件中添加权限。下面是一个Info.plist的例子,其中有一个所有可能的权限的完整列表。

这是因为permission_handler插件涉及到所有不同的SDK,而且静态代码分析器(Apple在提交应用程序时运行)会检测到这一点,如果它在Info.plist中找不到匹配的权限选项,就会发生断言。

permission_handler插件使用宏来控制一个权限是否被启用。

你必须列出你想在你的应用程序中使用的权限。

  1. 在你的Podfile文件中加入以下内容:
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      ... # Here are some configurations automatically generated by flutter

      # You can enable the permissions needed here. For example to enable camera
      # permission, just remove the `#` character in front so it looks like this:
      #
      # ## dart: PermissionGroup.camera
      # 'PERMISSION_CAMERA=1'
      #
      #  Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

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

        ## dart: PermissionGroup.reminders
        # 'PERMISSION_REMINDERS=1',

        ## dart: PermissionGroup.contacts
        # 'PERMISSION_CONTACTS=1',

        ## dart: PermissionGroup.camera
        # 'PERMISSION_CAMERA=1',

        ## dart: PermissionGroup.microphone
        # 'PERMISSION_MICROPHONE=1',

        ## dart: PermissionGroup.speech
        # 'PERMISSION_SPEECH_RECOGNIZER=1',

        ## dart: PermissionGroup.photos
        # 'PERMISSION_PHOTOS=1',

        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        # 'PERMISSION_LOCATION=1',

        ## dart: PermissionGroup.notification
        # 'PERMISSION_NOTIFICATIONS=1',

        ## dart: PermissionGroup.mediaLibrary
        # 'PERMISSION_MEDIA_LIBRARY=1',

        ## dart: PermissionGroup.sensors
        # 'PERMISSION_SENSORS=1',   

        ## dart: PermissionGroup.bluetooth
        # 'PERMISSION_BLUETOOTH=1',

        ## dart: PermissionGroup.appTrackingTransparency
        # 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',

        ## dart: PermissionGroup.criticalAlerts
        # 'PERMISSION_CRITICAL_ALERTS=1'
      ]

    end
  end
end
  1. 移除你想使用的权限前面的#字符。例如,如果你需要访问日历,确保代码看起来像这样。
## dart: PermissionGroup.calendar
        'PERMISSION_EVENTS=1',
  1. 删除Info.plist中相应的权限描述,例如,当你不需要相机权限时,只需删除’NSCameraUsageDescription’。

  2. Clean & Rebuild

咋用捏

有许多权限。你可以得到一个权限的状态:它分别是授予的、拒绝的、限制的或永久拒绝。

var status = await Permission.camera.status;
if (status.isDenied) {
  // We didn't ask for permission yet or the permission has been denied before but not permanently.
}

// 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() 来请求它。如果它之前已经被授予,则不会发生任何事情。
request() 返回该权限的新状态。

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

针对有些权限,例如位置或加速度传感器的权限,有一个相关的服务,可以启用或禁用。

if (await Permission.locationWhenInUse.serviceStatus.isEnabled) {
  // Use location.
}

你也可以打开应用程序的设置。

if (await Permission.speech.isPermanentlyDenied) {
  // The user opted to never again see the permission request dialog for this
  // app. The only way to change the permission's status now is to let the
  // user manually enable it in the system settings.
  openAppSettings();
}

在安卓系统上,你可以显示使用权限的理由。

bool isShown = await Permission.contacts.shouldShowRequestRationale;

有些权限不会显示要求用户允许或拒绝所请求的权限的对话框。
这是因为应用程序的操作系统设置正在为相应的权限进行检索。
设置的状态将决定该权限是被授予还是被拒绝。

以下权限将不显示对话框:

  • 通知
  • 蓝牙

以下权限将不显示对话框,但会打开相应的设置意图让用户改变权限状态:

  • manageExternalStorage
  • systemAlertWindow
  • requestInstallPackages
  • accessNotificationPolicy

locationAlways权限不能直接申请,用户必须先申请locationWhenInUse权限。通过点击 “Allow While Using App “接受这个权限,用户就有可能申请locationAlways权限。
然后会弹出另一个权限窗口,要求你保留 “仅在使用时 “或 “更改为始终允许”。

以上所有源代码,您可以移步:https://github.com/reasonpun/my_100_goals/tree/main/goals_04