当我尝试将文件写入特定文件夹时,Flutter 访问被拒绝

Flutter access denied , when i try to write a file into a specific folder

我正在尝试将文本文件写入特定位置(该位置由用户使用 file_picker 选择,我希望该文件对用户可见)

我加了

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

进入AndroidManifest.xml,并在运行时请求访问

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:permission_handler/permission_handler.dart';

void main() => runApp(MaterialApp(home: MyHomePage()));

class MyHomePage extends StatelessWidget {
  @override
  Future<void> write() async {
    var status = await Permission.storage.request();

    if (status.isGranted) {
      String directory = await FilePicker.getDirectoryPath();
      var status = await Permission.storage.request();
      File file = File(directory + 'test.txt');
      file.createSync();

      file.writeAsStringSync(
          'Here is some text to test the ability to write to external folder');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FlatButton(
          child: Text('Write to file'),
          onPressed: () {
            write();
          },
        ),
      ),
    );
  }
}

出现这个错误

D/EGL_emulation(31407): eglMakeCurrent: 0xe9467200: ver 3 0 (tinfo 0xe940f630)
I/FilePickerDelegate(31407): [SingleFilePick] File URI:content://com.android.providers.downloads.documents/tree/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2Ffoo/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2Ffoo
I/FilePickerDelegate(31407): Absolute file path:/
D/eglCodecCommon(31407): setVertexArrayObject: set vao to 0 (0) 0 0
D/EGL_emulation(31407): eglCreateContext: 0xdde235c0: maj 3 min 0 rcv 3
D/EGL_emulation(31407): eglMakeCurrent: 0xdde235c0: ver 3 0 (tinfo 0xdde38a70)
D/EGL_emulation(31407): eglMakeCurrent: 0xe9467200: ver 3 0 (tinfo 0xe940f630)
E/flutter (31407): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: FileSystemException: Cannot create file, path = '/test.txt' (OS Error: Read-only file system, errno = 30)
E/flutter (31407): #0      _File.throwIfError (dart:io/file_impl.dart:645:7)
E/flutter (31407): #1      _File.createSync (dart:io/file_impl.dart:283:5)
E/flutter (31407): #2      MyHomePage.write (package:store_to_phone_files/main.dart:18:12)
E/flutter (31407): <asynchronous suspension>
E/flutter (31407): #3      MyHomePage.build.<anonymous closure> (package:store_to_phone_files/main.dart:32:13)
E/flutter (31407): #4      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:779:19)
E/flutter (31407): #5      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:862:36)
E/flutter (31407): #6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter (31407): #7      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:504:11)
E/flutter (31407): #8      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:282:5)
E/flutter (31407): #9      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:217:7)
E/flutter (31407): #10     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:475:9)
E/flutter (31407): #11     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12)
E/flutter (31407): #12     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:122:9)
E/flutter (31407): #13     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
E/flutter (31407): #14     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:120:18)
E/flutter (31407): #15     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:106:7)
E/flutter (31407): #16     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
E/flutter (31407): #17     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
E/flutter (31407): #18     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
E/flutter (31407): #19     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
E/flutter (31407): #20     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
E/flutter (31407): #21     _rootRunUnary (dart:async/zone.dart:1196:13)
E/flutter (31407): #22     _CustomZone.runUnary (dart:async/zone.dart:1085:19)
E/flutter (31407): #23     _CustomZone.runUnaryGuarded (dart:async/zone.dart:987:7)
E/flutter (31407): #24     _invoke1 (dart:ui/hooks.dart:275:10)
E/flutter (31407): #25     _dispatchPointerDataPacket (dart:ui/hooks.dart:184:5)
E/flutter (31407): 
D/EGL_emulation(31407): eglMakeCurrent: 0xdde235c0: ver 3 0 (tinfo 0xdde38a70)
D/eglCodecCommon(31407): setVertexArrayObject: set vao to 0 (0) 0 0

注意:我知道我可以使用 path_provider 将文件写入应用程序目录,但我希望用户选择文件位置并且我希望用户可以看到该文件。

FilePicker.getDirectoryPath() 不是 return 一个有效的目录(它 return 是一个相对路径)我不知道为什么。

所以当我手动写的时候

 String directory = '/storage/emulated/0/Download/';

有效

我在 https://github.com/miguelpruivo/flutter_file_picker/wiki/Troubleshooting 找到了这个:

Issue: I'm picking a directory through getDirectoryPath() but it throws an error or an empty path. Possible solution: On Android, there are a few directories that can't be picked to be written "manually", one of those, is the downloads folder which may even return just an empty path (/).

感谢 blackapps。