Flutter-Android-Export 外部存储的读写

  • 需求:用户可以将音频转录的文本内容,导出为多种格式的文件
  • 实现:file_picker文件选择功能包 permission_handler应用权限请求包

首先:配置应用的存储权限: Android -> app -> src -> main ->AndroidManifest.xml

xml 复制代码
<!-- 添加存储权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
        android:requestLegacyExternalStorage="true"> 
</application>       
  Android 10以上对外部存储空间更严格的限制和更细粒度的控制 需要开启
  将 android:requestLegacyExternalStorage 设置为 true 可以使您的应用在运行于Android 10的设备上时继续使用传统的存储模型,而不是新引入的Scoped Storage模型。这允许应用像在Android 9及更低版本中一样访问外部存储。

导出.txt到公共存储外部存储

首先导出时需要保证用户是否有权限

ini 复制代码
 Future<bool> _requestPermission() async {
    PermissionStatus status = await Permission.storage.status;
    if (!status.isGranted) {
      status = await Permission.storage.request();
    }
    return status.isGranted;
 }

然后点击导出为.txt文件 _selectPath('text', 'txt', '你好')

获取选择目录路径

点击导出弹出先进行权限认证完成后 打开文件路径选择器 file_pick 提供打选择目录api 返回外部存储的路径

ini 复制代码
String? selectedDirectory =
            await FilePicker.platform.getDirectoryPath();

然后进行写入文件

ini 复制代码
String filePath = '$selectedDirectory/$title.$extension';
File file = File(filePath);
print('file$file');
await file.writeAsString(content);

最大的难点可能就是 权限问题

PathAccessException: Cannot open file, path = '/storage/emulated/0/Android/media/example.txt' (OS Error: Operation not permitted, errno = 1)

解决方案就是 需要通过对权限进行配置 以及插件来 检测 让用户去开启应用的权限 继续使用

完整代码

dart 复制代码
Future<void> _selectPath(BuildContext context, String title, String extension,
      String content) async {
    if (await _requestPermission()) {
      try {
        String? selectedDirectory =
            await FilePicker.platform.getDirectoryPath();
        print('selectedDirectory: $selectedDirectory');
        if (selectedDirectory == null) {
          print('用户取消了选择');
        } else {
          Directory directory = Directory(selectedDirectory);
          if (await directory.exists()) {
            String filePath = '$selectedDirectory/$title.$extension';
            File file = File(filePath);
            print('file$file');
            await file.writeAsString(content);
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text('已保存 $title 文件到 $filePath')),
            );
          } else {
            print('选择的目录不存在');
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text('选择的目录不存在')),
            );
          }
        }
      } catch (e) {
        print('选择路径或写入文件时出现异常:$e');
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('发生错误:$e')),
        );
      }
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('需要存储权限才能保存文件。')),
      );
    }
  }

希望可以帮到你

相关推荐
用户2018792831675 小时前
AMS和app通信的小秘密
android
用户2018792831675 小时前
ThreadPoolExecutor之市场雇工的故事
android
诺诺Okami5 小时前
Android Framework-Launcher-InvariantDeviceProfile
android
Antonio9156 小时前
【音视频】Android NDK 与.so库适配
android·音视频
sun00770015 小时前
android ndk编译valgrind
android
AI视觉网奇16 小时前
android studio 断点无效
android·ide·android studio
jiaxi的天空16 小时前
android studio gradle 访问不了
android·ide·android studio
No Silver Bullet17 小时前
android组包时会把从maven私服获取的包下载到本地吗
android
catchadmin17 小时前
PHP serialize 序列化完全指南
android·开发语言·php
星秋Eliot17 小时前
Flutter多线程
flutter·async/await·isolate·flutter 多线程