【问题标题】:Getting permission to the external storage (file_provider plugin)获取外部存储的权限(file_provider 插件)
【发布时间】:2018-11-06 18:34:27
【问题描述】:

我在使用颤振的 android 设备上获取外部存储权限时遇到了一些问题。

当我尝试在我的外部存储中创建一个目录时,我收到了这个错误(我只是为了这个示例更改了目录。在我自己的项目中,目录名称不同):

I/flutter (12727): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
I/flutter (12727): The following FileSystemException was thrown while handling a gesture:
I/flutter (12727): Creation failed, path = '/storage/emulated/0/com.domain.bundle' (OS Error: Permission denied,
I/flutter (12727): errno = 13)
I/flutter (12727): 

我已经添加了
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
到清单文件并重建整个项目。我还能尝试什么?

此外,仅列出外部存储中的所有文件也会产生相同的权限错误。

希望听到!

【问题讨论】:

  • 你手机的安卓版本是多少?
  • 我的手机上安装了 Android 8.0.0。但可以这么说,它需要全面发挥作用。
  • 您使用的是哪个插件?你能检查一下你的应用程序的设置中是否启用了权限吗?
  • 我没有使用插件。我正在使用 path_provider 作为扩展存储的路径,并尝试在给定位置创建一个目录
  • 能否在设置中检查权限是否启用(允许)?

标签: flutter


【解决方案1】:

除了需要将WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE 添加到您的android/app/src/main/AndroidManifest.xml 之外

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xxx.yyy">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
...
</manifest>

您还需要运行时请求权限,使用simple_permissions 包:

import 'package:simple_permissions/simple_permissions.dart';

PermissionStatus permissionResult = await SimplePermissions.requestPermission(Permission. WriteExternalStorage);
if (permissionResult == PermissionStatus.authorized){
  // code of read or write file in external storage (SD card)
}

注意:

  1. 第一次运行SimplePermissions.requestPermission时,应用会弹出一个窗口,您必须点击ALLOW

给予许可。

  1. 如果您已经点击了DENY,请卸载调试应用程序并重新调试它以安装和修复此问题 -> 触发弹出窗口并让您有机会点击ALLOW

【讨论】:

  • 这不起作用并且错误不会消失。请帮我 。我正在使用 API 28 安卓模拟器
  • 您的权限是否被拒绝?
  • 是的,我做到了。请修复它
  • 我需要查看您的代码。请使用示例代码提出一个新问题。最好是如果您拥有具有权限的基本 helloworld 应用程序。
  • SimplePermissions 插件不工作且不再受支持。
【解决方案2】:

在 Android Q 中,此错误将通过在 AndroidManifest 文件中添加以下行来解决:

 <application
      android:requestLegacyExternalStorage="true"

【讨论】:

    【解决方案3】:

    请使用包 permission_handler 请求权限。
    https://pub.dev/packages/permission_handler
    https://github.com/BaseflowIT/flutter-permission-handler

    import 'package:permission_handler/permission_handler.dart';
    
    ...
    
    void _showFilesinDir({Directory dir}) {
        dir.list(recursive: false, followLinks: false)
        .listen((FileSystemEntity entity) {
          print(entity.path);
        });
      }
    
    ...
    
    onTap: () async{
                Map<PermissionGroup, PermissionStatus> permissions = await PermissionHandler().requestPermissions([PermissionGroup.storage]);
    
                var systemTempDir = Directory.systemTemp;
                _showFilesinDir(dir: systemTempDir);
    
                final myDir = new Directory('/sdcard');
                myDir.exists().then((isThere) {
                  isThere ? _showFilesinDir(dir: myDir) : print('non-existent');
                });
    
              }
    ...
    

    模拟器的结果是这样的:

    I/flutter (19980): /data/user/0/xxx.login_challenge/code_cache/flutter_engine <br>
    I/flutter (19980): /data/user/0/xxx.login_challenge/code_cache/login_challengeMSBLSX <br>
    ...
    I/flutter (19980): /sdcard/Android <br>
    

    【讨论】:

    • 我正在尝试访问 /storage/emulated/ 目录但收到错误“未处理的异常:FileSystemException:目录列表失败,路径 = '/storage/emulated/'(操作系统错误:权限被拒绝,errno = 13)" 虽然我已授予 WRITE_EXTERNAL_STORAGE 和 READ_EXTERNAL_STORAGE 权限。任何建议。谢谢。
    • @Kamlesh,您能否将重现代码发布到一个新问题。如果您使用 Android 10,则需要 medium.com/@sriramaripirala/…
    【解决方案4】:

    对于 Android 6.0 及更高版本,如果应用具有需要危险权限 (list of dangerous permissions) 的功能,则必须明确请求权限(查看图片here

    您已将权限添加到 Manifest 文件,这还不够,您还需要为您的权限实现运行时请求。

    我查看了 Flutter 存储库,似乎他们正在为此开发插件。这里是their discussion

    【讨论】:

      【解决方案5】:

      可能的解决方案:

      即使在添加权限后,我也遇到了同样的错误(在 Android 10 设备中)

      然后我,从设备中手动卸载 Flutter App,

      然后重新运行它。

      注意:确保安装后,从应用设置中允许存储权限

      挣扎了几个小时后它对我有用(我不知道为什么这个解决方案有效)

      【讨论】:

        【解决方案6】:

        可以像这样使用 permission_handler 包提供的运行时请求权限:

        await PermissionHandler().requestPermissions([PermissionGroup.storage]);
        

        为了确保授予正确的权限,请使用以下示例代码:

        ServiceStatus serviceStatus = await 
        PermissionHandler().checkServiceStatus(PermissionGroup.storage);
        if (serviceStatus.value == 1){
        // permission is granted
        }
        

        【讨论】:

        • 我想你的解决方案使用了一个插件,而你没有提到它
        猜你喜欢
        • 2017-08-26
        • 1970-01-01
        • 2017-08-17
        • 1970-01-01
        • 1970-01-01
        • 2017-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多