You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter获取用户权限(网络、存储、短信等):iOS与Android适配方案

嘿,这个问题我熟!在Flutter里跨平台处理Internet、Storage、SMS这类权限请求,最常用也最靠谱的方案就是借助permission_handler包来实现,下面我一步步给你拆解,保证iOS和Android都能完美适配:

第一步:添加依赖并初始化

首先在你的pubspec.yaml里引入权限处理包:

dependencies:
  flutter:
    sdk: flutter
  permission_handler: ^10.2.0 # 用最新稳定版就行
  device_info_plus: ^9.0.2 # 可选,用来判断Android版本做适配

执行flutter pub get安装依赖。

第二步:Android平台配置

Android需要在AndroidManifest.xml(路径:android/app/src/main/AndroidManifest.xml)里声明所需权限,不同权限对应不同的声明:

<!-- 网络权限(默认模板可能已有,但建议显式声明) -->
<uses-permission android:name="android.permission.INTERNET" />

<!-- 存储权限适配:Android 13+用媒体权限,12及以下用旧存储权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

<!-- SMS权限 -->
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />

注意:如果你的应用targetSdkVersion是33+,旧的READ_EXTERNAL_STORAGE已经失效,必须用新的媒体权限。

第三步:iOS平台配置

iOS要求必须在Info.plist(路径:ios/Runner/Info.plist)里添加权限用途描述,否则会直接崩溃或审核不通过:

<!-- 网络权限:如果需要访问非HTTPS资源,需添加这个配置 -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

<!-- 存储权限(相册访问) -->
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问您的相册来保存和读取图片/视频</string>

<!-- SMS权限 -->
<key>NSMessagesUsageDescription</key>
<string>需要发送短信完成验证,或读取短信获取验证码</string>

⚠️ 描述内容一定要真实,不能随便写,否则App Store审核会被驳回。

第四步:Flutter代码实现权限请求

接下来写核心的权限请求逻辑,包括权限检查、请求、以及永久拒绝后的引导:

首先导入所需包:

import 'package:permission_handler/permission_handler.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'dart:io';

然后封装一个通用的权限处理方法:

/// 检查并请求指定权限
Future<bool> requestPermission(Permission permission) async {
  final status = await permission.status;
  
  if (status.isGranted) {
    return true;
  } else if (status.isDenied) {
    // 第一次请求权限
    final result = await permission.request();
    return result.isGranted;
  } else if (status.isPermanentlyDenied) {
    // 用户永久拒绝,引导去设置页开启
    await openAppSettings();
    return false;
  } else if (status.isRestricted) {
    // iOS上家长控制等限制导致权限无法获取
    return false;
  }
  
  return false;
}

然后针对不同权限调用这个方法,注意Android版本的适配:

// 请求网络权限(Android默认允许,iOS也默认开放,但如果需要蜂窝数据权限可以用Permission.phone)
bool hasInternet = await requestPermission(Permission.internet);

// 请求存储权限:根据Android版本切换权限类型
Permission storagePermission;
if (Platform.isAndroid) {
  final androidInfo = await DeviceInfoPlugin().androidInfo;
  if (androidInfo.version.sdkInt >= 33) {
    storagePermission = Permission.photos; // Android 13+用相册权限
  } else {
    storagePermission = Permission.storage; // 旧版本用存储权限
  }
} else {
  storagePermission = Permission.photos; // iOS统一用相册权限
}
bool hasStorage = await requestPermission(storagePermission);

// 请求SMS权限
bool hasSms = await requestPermission(Permission.sms);

最后建议:权限请求最好在用户主动触发的操作(比如点击"上传图片"按钮)后再发起,不要一启动App就弹权限请求,这样用户体验更好,也能降低被拒绝的概率。

内容的提问来源于stack exchange,提问作者user10680274

火山引擎 最新活动