You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中用Dio和pathProvider下载文件完成却找不到文件

解决Android 13下Dio下载文件后无法找到的问题

问题原因

你使用了getTemporaryDirectory()获取临时目录,这个目录属于应用私有目录,仅当前应用可访问,系统文件管理器和其他应用无法读取,所以你找不到下载的文件。此外,Android 13对公共存储的访问权限有更新,需要适配权限规则。

修复步骤

1. 切换到公共下载目录

使用path_provider的getDownloadsDirectory()替代临时目录,这个目录是系统公共下载文件夹,用户可通过文件管理器直接找到。

2. 适配Android 13权限

在AndroidManifest.xml中添加对应权限:

<!-- 适配Android 12及以下版本的存储权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Android 13及以上,根据文件类型添加读取权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

3. 修改代码实现

更新下载逻辑,切换存储目录并确保权限申请:

import 'package:permission_handler/permission_handler.dart'; // 需要添加permission_handler依赖

void onDownloadClick(String url) async {
  // 先申请权限
  var status = await Permission.storage.request();
  if (status.isGranted) {
    String fileName = url.split("/").last;
    var downloadsDir = await getDownloadsDirectory();
    if (downloadsDir != null) {
      String fullPath = '${downloadsDir.path}/$fileName';
      debugPrint('full path $fullPath');
      var dio = Dio();
      await download2(dio, url, fullPath); // 添加await确保下载完成
    }
  } else {
    debugPrint("存储权限被拒绝");
  }
}

Future download2(Dio dio, String url, String savePath) async {
  try {
    Response response = await dio.get(
      url,
      onReceiveProgress: showDownloadProgress,
      options: Options(
        responseType: ResponseType.bytes,
        followRedirects: false,
        validateStatus: (status) {
          return status! < 500;
        },
      ),
    );
    debugPrint(response.headers.toString());
    File file = File(savePath);
    var raf = file.openSync(mode: FileMode.write);
    raf.writeFromSync(response.data);
    await raf.close();
    debugPrint("文件已保存到:$savePath");
  } catch (e) {
    debugPrint("下载错误:${e.toString()}");
  }
}

void showDownloadProgress(received, total) {
  if (total != -1) {
    debugPrint("${(received / total * 100).toStringAsFixed(0)}%");
  }
}

4. 补充说明

  • 需要在pubspec.yaml中添加permission_handler依赖:
    dependencies:
      permission_handler: ^10.2.0 # 使用最新稳定版本
    
  • 如果下载的是非媒体文件(如文档),Android 13下仍需使用MANAGE_EXTERNAL_STORAGE权限,但该权限需要在Google Play审核中说明用途,建议优先使用MediaStore API处理非媒体文件。

内容的提问来源于stack exchange,提问作者sudhanshu shaurya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:52:49