【问题标题】:How to save File in Downloads folder in flutter?如何在颤动中将文件保存在下载文件夹中?
【发布时间】:2021-10-15 23:10:34
【问题描述】:

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

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

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

正确的做法是什么?

【问题讨论】:

    标签: flutter


    【解决方案1】:

    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');
    

    如果您将尝试保存的任何文件写入该目录,它将显示在任何标准文件管理器应用程序的“下载”文件夹中,而不仅仅是 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);
    

    【讨论】:

      【解决方案2】:

      [已解决] 要找到正确的路径,请使用ext_storage。 您将需要此权限

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

      在 Android 10 上,您需要在清单中使用它

      <application
            android:requestLegacyExternalStorage="true"
      

      在 Android 11 上改用这个

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

      记得使用 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);
        }
      

      【讨论】:

        【解决方案3】:

        你想要getExternalStorageDirectories。您可以传递一个参数来具体指定下载:

        final directory = (await getExternalStorageDirectories(type: StorageDirectory.downloads)).first!;
        
        File file2 = File("${directory.path}/test.txt");
        await file2.writeAsString('TEST ONE');
        

        如果您使用空安全,则不需要 bang 运算符:

        final directory = (await getExternalStorageDirectories(type: StorageDirectory.downloads)).first;
        
        File file2 = File("${directory.path}/test.txt");
        await file2.writeAsString('TEST ONE');
        

        【讨论】:

        • 我尝试打印路径,我认为这是正确的:“/storage/emulated/0/Android/data/com.my.app/files/Download”但我找不到文件,有什么想法吗?
        • @EmanueleVinci 您可能在某处忽略了一个异常。您可能没有授予写入外部存储的权限。请参阅此答案以了解如何:stackoverflow.com/a/50571167/13250142。您在清单和运行时都需要权限。这是一个猜测,所以请提供更多详细信息,说明您为查找文件所做的工作、您正在运行的代码的输出、您尝试解决的任何问题(例如,立即读回您刚刚出错的文件你的飞镖代码)。
        • 问题解决了一半!我有 ,我正确地询问了权限,但问题是使用 Android 11 你需要 。无论如何,文件应用程序无法访问路径“/storage/emulated/0/Android/data/com.my.app/files/Download”。有什么想法吗?
        • @EmanueleVinci exact 错误是什么。
        • 确切的问题是 Android 11 使用这个新权限在存储上写入 (WRITE_EXTERNAL_STORAGE),你没有收到任何异常,没有消息,任何东西......我已经在另一个上尝试过你的代码装有Android 9的手机,它可以工作!现在要在我的 Android 11 手机上测试它,我需要了解如何保存在下载文件夹中
        猜你喜欢
        • 2021-06-22
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        • 2021-08-21
        • 2021-08-28
        • 2021-04-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多