即使授予了存储权限,也无法在Samsung手机上创建目录被拒绝

问题描述

启动我的应用程序时,我在存储中创建了一个文件夹。为此,我要求在initState()中获得许可。只有完成后,目录检查才能继续进行。

@override
  void initState(){
    super.initState();
    easyDir = Directory(widget.folderPath);
    getPermissionStatus().whenComplete(() {
      setState(() {
        //never call async operations in setState,do it in a function call.
        directoryCheck();
      });
    });
  }

folderPathpermission_handler包产生。我的手机上的哪个是/storage/emulated/0/Documents/easyFolder

  //check if directory exists,create if not.
  Future<void> directoryCheck() async {
    // using awaits fixed my problem of setstate being called before
    // directory was created.. and calling setState at end
    exists = await easyDir.exists();
    if (!exists){
      await new Directory(widget.folderPath).create(recursive: true);
      exists = true;
    }
    setState(() {

    });

  }

Future<void> getPermissionStatus() async {
    _status = await Permission.storage.status;
    // if permission is not granted yet,request it and update _status
    if (_status != PermissionStatus.granted){
      await Permission.storage.request();
      _status = await Permission.storage.status;
    }
  }

这在模拟器上按预期工作。该应用程序在启动时会请求许可,等待其完成,并在允许时创建目录。

但是当安装在我的Samsung手机甚至是朋友手机(Samsung手机)上时,即使授予了权限,也会由于拒绝权限而无法创建该文件夹。

这是我在三星手机上收到的错误:

E/flutter (23275): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: FileSystemException: Creation failed,path = '/storage/emulated/0/Documents' (OS Error: Permission denied,errno = 13)

我显然在启动应用程序时获得了许可。更重要的是,当我进入应用程序的appinfo时,它显示已授予Storage权限。

我尝试在华为和小米手机上安装它,并且都按预期工作。

我在做什么错了?

这是我的AndroindManifest

中的权限行
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>

如果有帮助,这里是错误堆栈:

E/flutter (23275): #0      _Directory.create.<anonymous closure> (dart:io/directory_impl.dart:124:11)
E/flutter (23275): #1      _rootRunUnary (dart:async/zone.dart:1192:38)
E/flutter (23275): #2      _CustomZone.runUnary (dart:async/zone.dart:1085:19)
E/flutter (23275): #3      _FutureListener.handleValue (dart:async/future_impl.dart:141:18)
E/flutter (23275): #4      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
E/flutter (23275): #5      Future._propagateToListeners (dart:async/future_impl.dart:711:32)
E/flutter (23275): #6      Future._completeWithValue (dart:async/future_impl.dart:526:5)
E/flutter (23275): #7      Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:556:7)
E/flutter (23275): #8      _rootRun (dart:async/zone.dart:1184:13)
E/flutter (23275): #9      _CustomZone.run (dart:async/zone.dart:1077:19)
E/flutter (23275): #10     _CustomZone.runGuarded (dart:async/zone.dart:979:7)
E/flutter (23275): #11     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1019:23)
E/flutter (23275): #12     _microtaskLoop (dart:async/schedule_microtask.dart:43:21)
E/flutter (23275): #13     _startMicrotaskLoop (dart:async/schedule_microtask.dart:52:5)
E/flutter (23275): 

解决方法

我觉得奇怪的是,该代码无法在Android 11上正常运行,但不能在10上运行,因为新的作用域存储会导致Android 10 (Q)及更高版本中的写入权限失败

现在在您的清单中尝试执行此操作,以选择退出Android 10中的范围存储(在Android 11中将不执行任何操作),

<manifest ... >
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<!-- This attribute is "false" by default on apps targeting
     Android 10 or higher. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

警告:更新应用程序以定位Android 11(API级别)后 30),系统会忽略requestLegacyExternalStorage属性 当您的应用在Android 11设备上运行时,因此您的应用必须 准备支持范围存储并为以下用户迁移应用数据 这些设备。

More info about Scoped Storage here

现在有一些问题可以帮助您解决此问题:

folderPath由Permission_handler生成

我不记得在请求权限时,Permission_handler会返回路径,您能否详细说明如何获得widget.folderPath

仿真器正在运行Android版本11。而我的三星手机是 在Android版本10上

华为和小米设备怎么样,它们也都运行Android 10吗?

您在gradle中的compileSdkVersion / targetSdkVersion或AndroidManifest中的targetSdk是什么?

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...