如何摆脱:“FileSystemException:无法打开文件,路径 = '...'(操作系统错误:权限被拒绝,errno = 13)”?

Col*_*ass 7 android flutter

我试图在我的 Flutter 应用程序中显示我手机中的图像并收到以下错误:

Another exception was thrown: FileSystemException: Cannot open file, path = '/storage/emulated/0/Android/data/com.android.providers.media/albumthumbs/1570277797774' (OS Error: Permission denied, errno = 13)
Run Code Online (Sandbox Code Playgroud)

我不明白这Permission denied部分,因为我添加了...

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Run Code Online (Sandbox Code Playgroud)

...到我的android/app/src/mainAndroidManifest.xml文件,当运行该应用程序时,它表明它确实具有读取文件的权限:
权限
此外,我尝试打开的文件存在并且看起来不错 - 我也可以用其他应用程序打开它: 要打开的文件 这是我的代码:

import 'dart:io';

import 'package:flutter/material.dart';

void main() => runApp(FileOps());

class FileOps extends StatefulWidget {
  _FileOpsState createState() => _FileOpsState();
}

class _FileOpsState extends State<FileOps> {
  File localFile;
  String widgetTitle = 'Show Image';

  @override
  void initState() {
    super.initState();
    localfile.then((File _localFile) {
      setState(() {
        localFile = _localFile;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: widgetTitle,
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text(widgetTitle),
        ),
        body: Column(
          children: <Widget>[
            Image.file(localFile),
          ],
        ),
      ),
    );
  }

  Future<File> get localfile async {
    String imgPath =
        '/storage/emulated/0/Android/data/com.android.providers.media/albumthumbs/1570277797774';
    return File(imgPath);
  }
}
Run Code Online (Sandbox Code Playgroud)

我的 pubspec.yaml:

name: template_app
description: A template Flutter app for testing and minimal examples

version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons:

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true
Run Code Online (Sandbox Code Playgroud)

对评论中问题的回答:

  • “com.android.providers.media”不是我的应用程序的名称,我知道它是什么 - 但我想打开的图像在那里
  • 我的 Android 版本是 8.0.0,我的手机也在运行 EMUI 8.0.0(具体是什么,一些华为的东西)
  • 我可以使用手机附带的标准应用程序打开文件,称为“画廊”

Col*_*ass 5

注意:我的回答现在有点旧了,我听说新版本的permission_handler工作方式现在有点不同 - 所以我猜现在只需谷歌它是如何工作的。

我明白了 -<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>似乎只定义了需要什么权限,但实际上并没有请求它们 :D
所以我手动请求了权限,然后一切正常:

我跟着这个教程

  1. 我添加permission_handler:pubspec.yaml
  2. 将我的get localfileget 方法更改为:
  Future<File> get localfile async {
    final PermissionHandler _permissionHandler = PermissionHandler();
    var result = await _permissionHandler.requestPermissions([PermissionGroup.storage]);
    if (result[PermissionGroup.storage] == PermissionStatus.granted) {
      // permission was granted
      String imgPath = '/storage/emulated/0/Android/data/com.android.providers.media/albumthumbs/1570277797774';
      return File(imgPath);
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 我还建议将 `android:requestLegacyExternalStorage="true"` 添加到您的 `&lt;application.../&gt;` 标记中,以适应 `Android Q` 及更高版本。 (3认同)

小智 5

对我有用的是

首先在 android/app/build.gradle 中

  • 将compileSdkVersion设置为29(当前最高)

  • 将您的 targetSdkVersion 设置为 29(当前最高)

其次在 android/app/src/main/AndroidManifest.xml 中

  • 将 android:requestLegacyExternalStorage="true 添加到标签中

然后重建并看看它是否适合您