簡體   English   中英

如何獲取使用 Flutter 保存文件的 Android 下載路徑?

[英]How to get the Android Downloads path for saving files using Flutter?

如何獲得可見的 Android 使用 Flutter 保存文件的下載路徑? 這可能是因為我在調試模式下運行應用程序,從 android-studio 設備管理器到物理連接的平板電腦,而不是安裝的應用程序?

我的 Flutter 應用程序從 API 下載任何類型的文件,我想將它們保存在下載文件夾中。 這似乎是一個簡單的問題,但我在 android 平板電腦的任何地方都找不到該文件。

此代碼返回/data/user/0/com.myapp/app_flutter/fatsquid.jpg

path_provider: ^2.0.11
import 'package:path_provider/path_provider.dart';
---
Future<String> getFilePath(uniqueFileName) async {
  String path = '';
  Directory dir = await getApplicationDocumentsDirectory();
  path = '${dir.path}/$uniqueFileName';
  return path;
}

我的意圖是將文件保存在可見目錄中,最好是下載文件夾。 我不需要用戶選擇目錄,類似於 web 瀏覽器。

我正在使用dio.download像這樣返回文件

  Future<void> downloadMobileFile(User user) async {
    log('downloading with mobile function ');
    setState(
      () {
        downloading = true;
        filename = user.downloadFileName;
      },
    );

    bool hasPermission = await _requestWritePermission();
    if (!hasPermission) return;

    String savePath = await getFilePath(user.downloadFileName);

    print(savePath);

    final storage = FlutterSecureStorage();

    String? token = await storage.read(key: 'jwt');

    Dio dio = Dio();

    dio.interceptors.add(LogInterceptor(responseBody: false));

    dio.download(
      user.fileUrl,
      savePath,
      options: Options(
        headers: {HttpHeaders.authorizationHeader: 'Bearer $token'},
      ),
      onReceiveProgress: (rcv, total) {
        setState(
          () {
            received =
                'received: ${rcv.toStringAsFixed(0)} out of total: ${total.toStringAsFixed(0)}';
            progress = ((rcv / total) * 100).toStringAsFixed(0);
          },
        );
        if (progress == '100') {
          setState(
            () {
              isDownloaded = true;
            },
          );
        } else if (double.parse(progress) < 100) {}
      },
      deleteOnError: true,
    ).then(
      (_) {
        print(progress);
        print(isDownloaded);

        setState(
          () {
            if (progress == '100') {
              isDownloaded = true;
            }
            downloading = false;
          },
        );
      },
    );
    // opens the file
    //OpenFile.open("${dir.path}/$fileName", type: 'application/pdf');
  }

  Future<bool> _requestWritePermission() async {
    await Permission.storage.request();
    return await Permission.storage.request().isGranted;
  }

控制台 output 從下載 function:

[log] downloading with mobile function 
I/flutter (12774): file download path
I/flutter (12774): /data/user/0/com.mydomain/app_flutter/fatsquid.jpg
I/flutter (12774): *** Request ***
I/flutter (12774): uri: https://api.mydomain.com/transcript/download/transcript/file/1
I/flutter (12774): method: GET
I/flutter (12774): responseType: ResponseType.stream
I/flutter (12774): followRedirects: true
I/flutter (12774): connectTimeout: 0
I/flutter (12774): sendTimeout: 0
I/flutter (12774): receiveTimeout: 0
I/flutter (12774): receiveDataWhenStatusError: true
I/flutter (12774): extra: {}
I/flutter (12774): headers:
I/flutter (12774):  authorization: Bearer toosecrettotell
I/flutter (12774): 
I/flutter (12774): *** Response ***
I/flutter (12774): uri: https://api.mydomain.com/transcript/download/transcript/file/1
I/flutter (12774): statusCode: 200
I/flutter (12774): headers:
I/flutter (12774):  content-type: application/octet-stream
I/flutter (12774):  date: Fri, 16 Sep 2022 06:02:40 GMT
I/flutter (12774):  vary: Origin
I/flutter (12774):  content-length: 497741
I/flutter (12774): 
I/flutter (12774): 100
I/flutter (12774): true
D/Surface (12774): Surface::disconnect(this=0x73ae0c8000,api=1)
D/Surface (12774): Surface::disconnect(this=0x73ae0c8000,api=-1)
D/Surface (12774): Surface::disconnect(this=0x7357103000,api=1)
I/GED     (12774): ged_boost_gpu_freq, level 100, eOrigin 2, final_idx 2, oppidx_max 2, oppidx_min 0
V/PhoneWindow(12774): DecorView setVisiblity: visibility = 4, Parent = android.view.ViewRootImpl@c627c36, this = DecorView@f8b8737[MainActivity]

我嘗試使用此代碼,但它返回了相同的目錄

  Future<String> getFileSavePath(String uniqueFileName) async {
    final Directory? dir = await getExternalStorageDirectory();
    String path = '${dir?.path}/$uniqueFileName';
    print("file download path");
    print(path);
    return path;
  }

我的android/app/src/main/AndroidManifest.xml文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example">

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

   <application

當我按照建議使用硬編碼字符串路徑時,出現此錯誤:

E/flutter (25145): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: FileSystemException: Cannot create file, path = '/storage/emulated/0/Download/fatsquid.jpg' (OS Error: Permission denied, errno = 13)

這個問題已經回答了。 你見過Flutter - 將文件保存到下載文件夾 - downloads_path_provider嗎?

path_provider 可能很快會發生一些變化,有一些未解決的問題:
https://github.com/flutter/flutter/issues/35783\截至目前,在 Android 設備上獲取下載路徑的最佳方法是使用:
/storage/emulated/0/Download/

https://github.com/flutter/flutter/issues/35783上的問題已關閉,path_provider package 沒有任何解決方案

所以你可以使用:

/storage/emulated/0/Download/

並且您可以確保在 manifest.xml 文件中添加您的權限:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM