如何在flutter中保存Downloads文件夹中的文件?

Ema*_*nci 15 flutter

在我的 flutter 应用程序中,我可以创建一个 pdf 文件,然后我想将其保存在下载文件夹中。我正在尝试使用 path_provider 包来实现这个目标,但我不能。

这是颤振食谱中的示例代码,如果我使用它,我不会收到任何错误,但我也找不到该文件。

final directory = await getApplicationDocumentsDirectory();
File file2 = File("${directory.path}/test.txt");
await file2.writeAsString('TEST ONE');
Run Code Online (Sandbox Code Playgroud)

正确的做法是什么?

Ema*_*nci 11

要找到正确的路径,请使用ext_storage。您将需要此许可

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

在 Android 10 上,您需要在清单中添加此内容

<application
      android:requestLegacyExternalStorage="true"
Run Code Online (Sandbox Code Playgroud)

在 Android 11 上使用此替代

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

记得使用permission_handler来请求他们

我给你留下我的代码:

  static Future saveInStorage(
      String fileName, File file, String extension) async {
    await _checkPermission();
    String _localPath = (await ExtStorage.getExternalStoragePublicDirectory(
        ExtStorage.DIRECTORY_DOWNLOADS))!;
    String filePath =
        _localPath + "/" + fileName.trim() + "_" + Uuid().v4() + extension;

    File fileDef = File(filePath);
    await fileDef.create(recursive: true);
    Uint8List bytes = await file.readAsBytes();
    await fileDef.writeAsBytes(bytes);
  }
Run Code Online (Sandbox Code Playgroud)

  • `ext_storage` 已停止使用 - 有什么好的替代方案吗? (4认同)

小智 8

Android 11 改变了很多事情,强调了范围存储。尽管 /storage/emulated/0/Android/data/com.my.app/files 是 path_provider pkg 给出的目录路径之一,但您将无法看到 /storage/emulated/0/Android 中保存的文件/data/com.my.app/files 仅使用任何普通的文件应用程序(Google Files、Samsung My Files 等)。

解决这个问题的一种方法(尽管它仅适用于 Android)是指定“常规”下载文件夹,如下所示。

Directory generalDownloadDir = Directory('/storage/emulated/0/Download');
Run Code Online (Sandbox Code Playgroud)

如果您写入尝试保存到该目录的任何文件,它将显示在任何标准文件管理器应用程序的“下载”文件夹中,而不仅仅是 path_provider pkg 提供的特定于应用程序的目录。

下面是我正在构建的应用程序中的一些测试代码,我将用户生成的二维码保存到用户的设备上。只是为了更清楚。

//this code "wraps" the qr widget into an image format
                          RenderRepaintBoundary boundary = key.currentContext!
                              .findRenderObject() as RenderRepaintBoundary;
                          //captures qr image 
                          var image = await boundary.toImage();

                          String qrName = qrTextController.text;
                          
                          ByteData? byteData =
                              await image.toByteData(format: ImageByteFormat.png);
                          Uint8List pngBytes = byteData!.buffer.asUint8List();

                          //general downloads folder (accessible by files app) ANDROID ONLY
                          Directory generalDownloadDir = Directory('/storage/emulated/0/Download'); //! THIS WORKS for android only !!!!!! 

                          //qr image file saved to general downloads folder
                          File qrJpg = await File('${generalDownloadDir.path}/$qrName.jpg').create();    
                          await qrJpg.writeAsBytes(pngBytes);

                          Fluttertoast.showToast(msg: ' $qrName QR code was downloaded to ' + generalDownloadDir.path.toString(), gravity: ToastGravity.TOP);
Run Code Online (Sandbox Code Playgroud)