经过多年的发展Android和iOS的权限变得越来越复杂,各个版本之前也有一些不同。所以本教程教大家如何获取Permission。

可随意转载!

前言

没有Android开发经验的学员会问:直接在AndroidManifest.xml配置user-permission不行吗?

早期的Android版本确实可以,安装App的时候就事先申请好一大堆的权限。但是这产生了一个问题:用户在使用前并不知道此App申请这么多权限干嘛?有什么风险?所以Android 6以后版本会要求开发者,在需要权限的时候,实时弹框跟用户申请。这就是本教程的要解决的问题。

本篇非常重要,在实际开发中经常用到!

创建项目

命令行执行以下命令:

flutter create -a java -i objc ability_permission

创建flutter项目,并且指定Android平台的编程语言为Java,iOS平台的编程语言为Objective-C。

打开Android Studio,选择Open an exist Android Studio Project

配置项目

编辑flutter配置文件pubspec.yaml ,如下图:

配置AndroidManifest.xml

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

扩展阅读:如果我们是读取App在外置存储的file和cache空间,是无需额外申请权限。另外Android 10 进一步收紧了权限,你可能需要配置参数requestLegacyExternalStorage 才能获得分区存储权限。

编写main.dart

1. import依赖包

import 'package:permission_handler/permission_handler.dart';

2. 定义类变量

  final Permission _permission;

3. 定义Flutter的UI函数

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(_permission.toString()),
      subtitle: Text(
        _permissionStatus.toString(),
        style: TextStyle(color: getPermissionColor()),
      ),
      trailing: IconButton(
          icon: const Icon(Icons.info),
          onPressed: () {
            checkServiceStatus(context, _permission);
          }),
      onTap: () {
        requestPermission(_permission);
      },
    );
  }

4. 定义Permission状态监听函数

  void _listenForPermissionStatus() async {
    final status = await _permission.status;
    setState(() => _permissionStatus = status);
  }

5. 定义Flutter的初始化函数

  @override
  void initState() {
    super.initState();

    _listenForPermissionStatus();
  }

6. 定义info图标点击弹出tip

  void checkServiceStatus(BuildContext context, Permission permission) async {
    Scaffold.of(context).showSnackBar(SnackBar(
      content: Text((await permission.status).toString()),
    ));
  }

扩展阅读:SnackBar是Scaffold widget下的组件,类似Android的Toast。它通过showSnackBar显示。比如:

final snackBar = SnackBar(
    context: Text('提示信息!')
)

7. 定义请求权限函数

  Future<void> requestPermission(Permission permission) async {
    final status = await permission.request();

    setState(() {
      print(status);
      _permissionStatus = status;
      print(_permissionStatus);
    });
  }

真机调试

因为我们在AndroidManifest.xml定义了storage相关的权限许可。所以我们可以动态获取到Permission.storage权限。反之,Permission.microphone权限是获取不到的。

机型适配问题

无,适配所有Android和iOS机型

示例代码

源码地址