Flutter 权限请求使用说明文档2025版,看过后念头通达

device_info: 2.0.3
permission_handler: 11.3.1

permission_handler 权限使用说明文档

📖 概述

permission_handler 是 Flutter 中最常用的权限请求插件。它提供了一个统一的 API 用于检查和请求 iOS 和 Android 平台的运行时权限。

本文档基于 permission_handler_platform_interface 中的 Permission 类源码,详细说明了每个权限的定义、平台差异、行为和使用注意事项。


🧾 权限列表(按功能分类)

1. 日历权限

权限平台说明备注
calendarAndroid, iOS访问设备日历。已弃用。请使用 calendarWriteOnlycalendarFullAccess
calendarWriteOnlyAndroid, iOS仅写入设备日历的权限。在 iOS 16 及更低版本上,此权限与 calendarFullAccess 相同。
calendarFullAccessAndroid, iOS读取和写入设备日历的权限。

2. 相机与媒体权限

权限平台说明备注
cameraAndroid, iOS访问设备的摄像头。iOS 上对应 Photos (相机胶卷和相机)。
mediaLibrary主要 iOS访问设备的媒体库(iOS 9.3+)。在 iOS 上,用于访问 Apple Music 等媒体内容,不是照片
photosAndroid, iOS访问设备的照片平台差异大
- iOS: Photos (iOS 14+ 读写访问级别)。
- Android:
- API 32 (Android 12) 及以下:使用 Permission.storage
- API 33 (Android 13) 及以上:应使用 Permission.photos
photosAddOnly仅 iOS仅添加照片到设备照片库的权限。iOS: Photos (14+ 仅添加访问级别)。如果想读取,需使用 photos
videosAndroid 13+访问设备外部存储中的视频文件Android API 33+。
audioAndroid 13+访问设备外部存储中的音频文件Android API 33+。
accessMediaLocationAndroid 10+访问用户共享集合中任何媒体文件包含的地理位置信息。Android API 29+。

3. 联系人、传感器与手机功能

权限平台说明备注
contactsAndroid, iOS访问设备的联系人。Android: Contacts
iOS: AddressBook
microphoneAndroid, iOS访问设备的麦克风。
sensorsAndroid, iOS访问设备的传感器。Android: Body Sensors
iOS: CoreMotion
sensorsAlwaysAndroid 13+后台访问设备的传感器。Android API 33+。
phone仅 Android访问设备手机状态(如电话号码、蜂窝网络信息)。PermissionWithService,可查询服务状态。
sms仅 Android发送和读取短信。
bluetoothAndroid, iOS访问设备的蓝牙适配器状态。PermissionWithService
iOS 13+: 需要授权。
iOS 13.0 注意: .status 可能不准确,请使用 .request() 并处理弹窗。
bluetoothScanAndroid 12+扫描蓝牙设备。Android API 31+。
bluetoothAdvertiseAndroid 12+广播蓝牙设备(使本设备可被其他设备发现)。Android API 31+。
bluetoothConnectAndroid 12+连接已配对的蓝牙设备。Android API 31+。
speechAndroid, iOS访问语音识别功能。平台行为不同:
- Android: 请求麦克风权限(同 microphone)。
- iOS: 请求语音访问权限(与 microphone 不同)。

4. 位置权限

权限平台说明备注
location3Android, iOS访问设备的粗略和精确定位。PermissionWithService
Android: Fine and Coarse Location
iOS: CoreLocation (Always and WhenInUse)
locationWhenInUse5Android, iOS仅在应用前台运行时访问设备位置。PermissionWithService
Android: Fine and Coarse Location
iOS: CoreLocation - WhenInUse
locationAlways4Android, iOS应用后台运行时也访问设备位置。PermissionWithService
注意: 在 Android 10+ 上,需要先获得前台定位权限,然后此权限会显示额外对话框或打开设置页。
iOS: CoreLocation - Always
activityRecognition19Android 10+访问活动识别(如检测用户步行、驾车等)。Android API 29+。

5. 存储权限

权限平台说明备注
storage15主要 Android访问外部存储。平台差异大:
- Android:
- API 33+: 此权限已弃用,总是返回 denied。请使用 photos, videos, audiomanageExternalStorage
- API 33-: 请求 READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE
- iOS: 访问 DocumentsDownloads 等文件夹。隐式授予
manageExternalStorage22Android 11+管理外部存储(范围存储下的广泛文件访问权限)。Android API 30+。
慎用: 应优先使用更隐私友好的 API(如 Storage Access Framework)。使用此权限可能需要向 Google Play 提交声明表。

6. 其他系统权限

权限平台说明备注
reminders11仅 iOS访问设备的提醒事项。
notification17Android, iOS推送通知。
ignoreBatteryOptimizations16仅 Android忽略电池优化(请求应用不被休眠)。
systemAlertWindow23仅 Android绘制系统警报窗口(悬浮窗)。
requestInstallPackages24Android 6.0+请求安装软件包。Android API 23+。
appTrackingTransparency25仅 iOS应用跟踪透明度(ATT)权限。用于请求跟踪用户 across apps 和网站的权限。
criticalAlerts26仅 iOS发送关键警报(绕过静音模式的通知)。
accessNotificationPolicy27Android 6.0+访问通知策略(如开关勿扰模式)。Android API 23+。
nearbyWifiDevices31Android 13+通过 Wi-Fi 连接附近设备。Android API 33+。
scheduleExactAlarm34Android 12+安排精确警报。Android API 31+。
assistant38Android, iOS助手权限。Android: 无
iOS: SiriKit
backgroundRefresh39仅 iOS读取当前后台应用刷新状态。

7. 特殊权限

权限说明
unknown20未知权限,仅用作返回类型,从不主动请求

🛠️ 核心类说明

Permission

  • 作用: 定义所有可以检查和请求的权限。
  • 核心属性: value (整数值,用于区分不同权限)。
  • 核心方法:
    • Permission.byValue(int value): 工厂构造函数,通过整数值创建 Permission 实例。
    • static const List<Permission> values: 所有可能的权限值列表。

PermissionWithService

  • 继承自: Permission
  • 作用: 一种特殊的权限,用于访问系统服务(如定位服务、蓝牙服务、电话服务)。除了拥有普通权限的检查和请求功能外,还可以查询相关服务的状态(例如,定位服务是否开启)。
  • 包含的权限: location, locationAlways, locationWhenInUse, phone, bluetooth

⚠️ 重要平台差异与使用指南

  1. Android 存储权限演变 (API 33 / Android 13+)

    • 问题: Permission.storage 在 Android 13+ 上已废弃并总是返回 denied
    • 解决方案:
      • 如果只需要访问媒体文件(图片、视频、音频),使用新的细分权限:
        • Permission.photos (图片)
        • Permission.videos (视频)
        • Permission.audio (音频)
      • 如果需要广泛的文件管理(访问所有文件),考虑使用 Permission.manageExternalStorage(但需注意商店审核政策)。
    • 代码适配示例:
      Future<Permission> getStoragePermission() async {
        if (Platform.isAndroid) {
          final androidInfo = await DeviceInfoPlugin().androidInfo;
          if (androidInfo.version.sdkInt <= 32) {
            // Android 12 (API 32) 及以下,使用 storage
            return Permission.storage;
          } else {
            // Android 13 (API 33) 及以上,使用 photos(假设你需要图片)
            return Permission.photos;
          }
        } else {
          // iOS 平台,使用 photos
          return Permission.photos;
        }
      }
      
      // 使用
      void checkPermission() async {
        Permission neededPermission = await getStoragePermission();
        var status = await neededPermission.status;
        if (status.isDenied) {
          status = await neededPermission.request();
        }
        // ... 处理状态
      }
      
  2. iOS 权限描述 (Info.plist)

    • 要求: 在请求任何敏感权限之前,必须在 ios/Runner/Info.plist 文件中添加相应的用途描述键和描述文字,否则可能导致请求失败或应用被拒绝。
    • 示例:
      • 相机: NSCameraUsageDescription
      • 相册: NSPhotoLibraryUsageDescription
      • 位置(始终): NSLocationAlwaysUsageDescription
      • 位置(使用时): NSLocationWhenInUseUsageDescription
      • 麦克风: NSMicrophoneUsageDescription
      • 语音识别: NSSpeechRecognitionUsageDescription
      • 追踪: NSUserTrackingUsageDescription (用于 appTrackingTransparency)
  3. Android 权限声明 (AndroidManifest.xml)

    • 要求: 同样需要在 android/app/src/main/AndroidManifest.xml 文件中声明你需要的权限。
    • 示例: <uses-permission android:name="android.permission.CAMERA" />
  4. 服务相关权限 (PermissionWithService)

    • 对于 location, bluetooth 等权限,除了检查 permission.status,还应检查 serviceEnabled(通过 PermissionWithService 的能力或其它专用API,如 location.serviceEnabled),因为用户可能关闭了设备的定位服务或蓝牙服务,即使权限已被授予。

💡 最佳实践与常见问题

  1. 按需请求: 在用户即将使用相关功能时才请求权限,而不是在应用启动时一次性请求所有权限。
  2. 解释原因: 在系统弹窗之前,自定义一个界面解释为什么需要这个权限,可以提高用户授权率。
  3. 处理“不再询问”: 如果 status.isPermanentlyDeniedtrue,应引导用户前往系统设置手动开启权限(使用 openAppSettings() 方法)。
  4. 真机测试: 务必在真实设备上测试权限流程,模拟器的行为可能与真机不一致。
  5. iOS 配置: 确保 Podfile 中已为 permission_handler 配置了所需的预处理器宏,以确保 iOS 权限检测正常工作。例如:
    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_CAMERA=1',
            'PERMISSION_PHOTOS=1',
            # ... 其他需要的权限
          ]
        end
      end
    end
    
  6. 版本检查: 对于 Android,使用 device_info_plus 等插件来获取系统版本号,以适配不同 API 级别的权限逻辑。

通过遵循本文档的说明,您可以更准确、更安全地在您的 Flutter 应用中处理各种运行时权限。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早起的年轻人

创作源于分享

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值