【flutter】使用 permission_handler 配置 Android 和 iOS 的权限

本文介绍了如何在Flutter中使用permission_handler插件进行权限管理,包括在Android和iOS两端的配置步骤,以及代码示例,帮助开发者解决权限配置问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

flutter在pub.flutter-io.cn插件库中有很多的关于权限配置的插件,但是就我个人而言,比较推荐使用permission_handler这个插件。当我们打开 permission_handler 时候,新手小白往往会因为它的官网文档弄得一头雾水。权限配置往往涉及到 Android 和 iOS 两个方向的相关知识,有可能大多数人就只会 Android 或 iOS 某一端知识,在配置权限时会出现屡屡不生效的问题,接下来我从零到一教你如何配置吧。

准备工作

flutter版本号:3.0.0
dart版本号:2.12.0

插件:permission_handler

一、使用步骤

1、使用的插件

permission_handler: ^9.0.2
flutter_easyloading: ^3.0.5

2、配置权限

Android 端:

(1)将以下内容添加到 gradle.properties 文件中:(针对androidX及以上的版本)

android.useAndroidX=true
android.enableJetifier=true

(2)将以下内容添加到 AndroidManifest.xml 文件中:(针对androidX及以上的版本)

android:hardwareAccelerated="true"

(3)按需在 AndroidManifest.xml 添加本项目需要用到的权限(本次以保存图片到本地相册举例)

<!-- 写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 读权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

iOS 端:

(1)将以下内容添加到您的 Podfile 文件中:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    ... # Here are some configurations automatically generated by flutter

    # Start of the permission_handler configuration
    target.build_configurations.each do |config|

      # 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_apple/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 of the permission_handler configuration
  end
end

(2)删除要使用的权限前面的字符 。例如,如果您需要访问相册,请确保代码如下所示:

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

(3)Info.plist 添加

<!-- 保存图片权限 -->
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Please allow the APP to save photos to the album</string>

二、代码示例

import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:permission_handler/permission_handler.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  /// 动态申请权限,需要区分android和ios,很多时候它两配置权限时各自的名称不同
  /// 此处以保存图片需要的配置为例
  Future<bool> requestPermission() async {
    late PermissionStatus status;
    // 1、读取系统权限的弹框
    if (Platform.isIOS) {
      status = await Permission.photosAddOnly.request();
    } else {
      status = await Permission.storage.request();
    }
    // 2、假如你点not allow后,下次点击不会在出现系统权限的弹框(系统权限的弹框只会出现一次),
    // 这时候需要你自己写一个弹框,然后去打开app权限的页面
    if (status != PermissionStatus.granted) {
      showCupertinoDialog(
          context: context,
          builder: (context) {
            return CupertinoAlertDialog(
              title: const Text('You need to grant album permissions'),
              content: const Text(
                  'Please go to your mobile phone to set the permission to open the corresponding album'),
              actions: <Widget>[
                CupertinoDialogAction(
                  child: const Text('cancle'),
                  onPressed: () {
                    Navigator.pop(context);
                  },
                ),
                CupertinoDialogAction(
                  child: const Text('confirm'),
                  onPressed: () {
                    Navigator.pop(context);
                    // 打开手机上该app权限的页面
                    openAppSettings();
                  },
                ),
              ],
            );
          });
    } else {
      return true;
    }
    return false;
  }

  // 保存网络图片
  saveNetworkImg(String imgUrl) async {
    // Todo
    // 处理保存网络图片的逻辑
    EasyLoading.showToast('处理保存网络图片的逻辑');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('home'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async{
          // 使用
          // 首先判断是否有权限,没权限就不执行了
          bool permission = await requestPermission();
          permission ? saveNetworkImg('imgUrl') : null;
        },
        child: const Icon(Icons.adb),
      ),
    );
  }
}

结果截图

Android:

 iOS:

<think>好的,我现在需要帮助用户解决在Flutter使用permission_handler配置安卓本地存储权限的问题。首先,我需要回顾用户提供的引用内容,看看是否有相关的信息。 根据引用[1],permission_handler插件需要同时配置AndroidiOS权限,用户可能遇到了配置不生效的问题。引用[2]提到了添加依赖的步骤,版本是7.1.0。引用[3]展示了如何在代码中请求权限,但具体到存储权限可能需要不同的PermissionGroup。引用[4]提到了iOS端的权限问题,但用户现在关注的是安卓端。 用户的问题明确,需要配置安卓的本地存储权限。首先,我应该分步骤说明配置流程。可能包括添加依赖、修改AndroidManifest.xml、动态请求权限等步骤。 需要注意的是,Android的存储权限在API 23(Android 6.0)之后需要动态请求,而不仅仅是声明在清单文件中。因此,用户需要在代码中处理运行时权限。 另外,安卓10(API 29)及以上版本引入了分区存储,可能需要处理不同的权限策略,比如使用READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE,或者考虑使用MANAGE_EXTERNAL_STORAGE,但后者可能需要特别处理,并且可能不被Google Play接受。因此,建议用户根据目标API级别选择合适的权限。 在代码示例部分,需要展示如何请求存储权限,可能使用Permission.storage,并检查权限状态是否为granted。同时,要提醒用户处理权限被拒绝的情况,比如引导用户到设置页面。 还要注意检查用户是否已经正确配置AndroidManifest.xml文件,添加了相应的权限声明。例如: <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 此外,可能需要处理Android 11(API 30)及以上的权限变更,比如使用MANAGE_EXTERNAL_STORAGE,但需要谨慎,因为Google Play可能有政策限制。因此,建议用户尽可能使用分区存储,减少对广泛存储权限的依赖。 总结步骤应该是: 1. 添加依赖 2. 配置AndroidManifest.xml 3. 动态请求权限 4. 处理权限结果 同时,生成相关问题时要考虑用户可能遇到的后续问题,比如权限被拒绝后的处理,不同安卓版本的适配等。</think>### 在Flutter配置Android本地存储权限的步骤 #### 1. 添加依赖 在 `pubspec.yaml` 文件中添加 `permission_handler` 依赖: ```yaml dependencies: permission_handler: ^10.4.4 # 使用最新稳定版本 ``` 运行 `flutter pub get` 安装依赖[^2]。 #### 2. 配置Android权限声明 在 `android/app/src/main/AndroidManifest.xml` 的 `<manifest>` 标签内添加以下权限: ```xml <!-- 存储权限Android 10及以下) --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Android 11及以上访问所有文件 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" /> ``` #### 3. 动态请求权限 在代码中使用 `Permission.storage` 请求存储权限: ```dart import 'package:permission_handler/permission_handler.dart'; // 检查并请求存储权限 Future<bool> requestStoragePermission() async { final status = await Permission.storage.request(); if (status.isGranted) { return true; } else if (status.isPermanentlyDenied) { // 引导用户手动开启权限 await openAppSettings(); } return false; } // 使用示例 void accessFile() async { if (await requestStoragePermission()) { // 执行文件操作 } else { print("权限被拒绝"); } } ``` #### 4. 适配Android版本 - **Android 10(API 29)及以上**:若需要访问媒体文件,建议使用 `READ_MEDIA_IMAGES`/`READ_MEDIA_VIDEO` 代替传统存储权限。 - **Android 13(API 33)及以上**:需单独请求 `READ_MEDIA_IMAGES` 或 `READ_MEDIA_VIDEO`[^1]。 #### 注意事项 - **分区存储**:从Android 11开始,Google推荐使用分区存储(Scoped Storage),尽量避免使用 `MANAGE_EXTERNAL_STORAGE`[^4]。 - **Google Play政策**:使用 `MANAGE_EXTERNAL_STORAGE` 需在应用商店提交「权限声明表」,否则可能被下架。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值