likes
comments
collection
share

【FlutterUtilCode】Flutter工具篇之PathUtils

作者站长头像
站长
· 阅读数 26

前言

FlutterUtilCode 是一个 Flutter 工具类集合插件,封装了常用的工具类函数,方便开发者调用。

本篇是 Flutter工具篇之PathUtils,系列文章内容主要介绍插件中工具类的功能、用法和代码实现等,感兴趣的同学可以持续关注。

FlutterUtilCode 系列(一)—— Flutter工具篇之LogUtils、SharedPerfsUtils

FlutterUtilCode 系列(二)—— Flutter工具篇之ToastUtils

FlutterUtilCode 系列(三)—— Flutter工具篇之UuidUtils

FlutterUtilCode 系列(四)—— Flutter工具篇之DeviceUtils

FlutterUtilCode 系列(五)—— Flutter工具篇之PathUtils

文件路径工具类-PathUtils

在 App 的开发中,文件的下载、缓存功能必不可少。在 Android 中,一般通过调用 Environment.getExternalStorageDirectory() 方法来获取外部存储设备的根目录路径。但是 Flutter 涉及到多端平台,那么我们如何获取呢,难道需要一个平台一个平台去实现吗?

不要着急,官方也考虑到了这个问题,所以推出了path_provider 插件,专门用来获取不同平台的文件路径。

【FlutterUtilCode】Flutter工具篇之PathUtils

官方出品,必属精品。path_provider 其 LIKES 数也是达到了 3.8K 非常收欢迎,目前已在 Android/iOS/Linux/MacOS/Windows 平台上支持。各平台支持的版本如下:

AndroidiOSLinuxmacOSWindows
SupportSDK 16+11.0+Any10.14+Windows 10+

一、代码实现

PathUtils 目前暂只支持 Android/iOS 平台的文件路径获取,后续会加上其他平台。实现功能如下:

1. App缓存路径

在 iOS 和 macOS 平台中,对应原生 NSCachesDirectory 方法获取到的路径。在 Android 平台中对应 Context.getCacheDir 方法获取到的路径。

/// App缓存路径
/// - `NSCachesDirectory` on iOS and macOS.
/// - `Context.getCacheDir` on Android.
static Future<String> getAppCachePath() async {
  // 如果不是Android或者iOS/macOS系统,则返回空字符串
  if (!_isAndroid && !_isIOSOrMacOS) return '';
  Directory directory = await getTemporaryDirectory();
  String path = directory.path;
  return path;
}

官方对于其他不支持平台调用会抛出一个 MissingPlatformDirectoryException 异常问题,我们这里优化下,对于 Android/iOS/macOS 以外的平台,直接返回空字符串。

2. App支持的存储路径

在 iOS 和 macOS 平台中,对应原生 NSApplicationSupportDirectory 方法的路径获取。在 Android 平台中对应 PathUtils.getFilesDir 方法的路径获取。PathUtils.getFilesDir是 Flutter engine 提供的一个用于获取应用程序私有目录路径的 API。在 Android 平台上,它返回的是 Context.getFilesDir() 方法获取到的路径。

  /// App支持的存储路径
  /// - `NSApplicationSupportDirectory` on iOS and macOS.
  /// - The Flutter engine's `PathUtils.getFilesDir` API on Android.
  static Future<String> getAppSupportPath() async {
    // 如果不是Android或者iOS/macOS系统,则返回空字符串
    if (!_isAndroid && !_isIOSOrMacOS) return '';
    Directory directory = await getApplicationSupportDirectory();
    return directory.path;
  }
3. App文档存储路径

在 iOS 和 macOS 平台中,对应原生 NSDocumentDirectory 方法的路径获取。在 Android 平台中对应 PathUtils.getDataDirectory 方法的路径获取。在 Android 平台上对应的也是 Context.getFilesDir() 方法获取到的路径。

  /// App文档路径
  /// - `NSDocumentDirectory` on iOS and macOS.
  /// - The Flutter engine's `PathUtils.getDataDirectory` API on Android.
  static Future<String> getAppDocPath() async {
    // 如果不是Android或者iOS/macOS系统,则返回空字符串
    if (!_isAndroid && !_isIOSOrMacOS) return '';
    Directory directory = await getApplicationDocumentsDirectory();
    return directory.path;
  }
4. 应用程序的下载目录路径(仅iOS/macOS支持)

该方法仅在 iOS/macOS 平台上支持。对应原生 NSSearchPathForDirectoriesInDomains.documentDirectory 方法的路径获取。具体是在应用程序沙盒中的 Documents/Downloads 目录路径,可以用于存储与应用程序相关的下载文件。

  /// 应用程序的下载目录路径,仅在 iOS/macOS 上支持
  static Future<String> getDownloadPath() async {
    // 如果不是iOS/macOS系统,则返回空字符串
    if (!_isIOSOrMacOS) return '';
    Directory? directory = await getDownloadsDirectory();
    return directory?.path ?? '';
  }
5. Android外部存储路径

该方法仅在 Android 平台上支持。对应原生 getExternalFilesDir(null) 方法的路径获取。

具体来说, Android 10及以上版本:/storage/emulated/0/Android/data/包名/files目录的路径。Android 9及以下版本:/sdcard/Android/data/包名/files目录的路径。

/// Android外部存储路径
/// - `getExternalFilesDir(null)` on Android.
static Future<String> getAndroidStoragePath() async {
  // 如果不是Android系统,则返回空字符串
  if (!_isAndroid) return '';
  Directory? directory = await getExternalStorageDirectory();
  return directory?.path ?? '';
}
6. Android外部存储缓存的所有路径

该方法仅在 Android 平台上支持。对应原生方法:

API level 19及以上:Context.getExternalCacheDirs() 方法的路径获取。

API level 18及以下:Context.getExternalCacheDir() 方法的路径获取。

/// Android外部存储缓存的所有路径
/// - Context.getExternalCacheDirs() on Android (or
///   Context.getExternalCacheDir() on API levels below 19).
static Future<List<String>> getAndroidExternalCachePaths() async {
  // 如果不是Android系统,则返回空字符串
  if (!_isAndroid) return [];
  List<Directory>? list = await getExternalCacheDirectories();
  return list?.map((d) => d.path).toList() ?? [];
}
7. Android外部存储-特定类型文件的路径

该方法仅在 Android 平台上支持。根据 StorageDirectoryType 枚举类来返回不同类型文件的路径。

static Future<List<String>> getAppExternalStoragePaths({StorageDirectoryType? type}) async {
  // 如果不是Android系统,则返回空字符串
  if (!_isAndroid) return [];
  List<Directory>? list = await getExternalStorageDirectories(type: _transformDirectoryType(type));
  return list?.map((d) => d.path).toList() ?? [];
}

StorageDirectoryType 枚举类对应类型如下:

  1. 获取Android外部存储-图片类型文件的路径,对应枚举 StorageDirectoryType.pictures

     /// 获取Android外部存储-图片类型文件的路径
     static Future<List<String>> getAndroidPicturePaths() async =>
         await getAppExternalStoragePaths(type: StorageDirectoryType.pictures);
    
  2. 获取Android外部存储-视频类型文件的路径,对应枚举 StorageDirectoryType.movies

    /// 获取Android外部存储-视频类型文件的路径
    static Future<List<String>> getAndroidMoviePaths() async =>
        await getAppExternalStoragePaths(type: StorageDirectoryType.movies);
    
  3. 获取Android外部存储-音频类型文件的路径,对应枚举 StorageDirectoryType.music

    /// 获取Android外部存储-音频类型文件的路径
    static Future<List<String>> getAndroidMusicPaths() async =>
        await getAppExternalStoragePaths(type: StorageDirectoryType.music);
    
  4. 获取Android外部存储-相机目录下的文件的路径,对应枚举 StorageDirectoryType.dcim

    /// 获取Android外部存储-相机目录下的文件的路径
    static Future<List<String>> getAndroidDCIMPaths() async =>
        await getAppExternalStoragePaths(type: StorageDirectoryType.dcim);
    
  5. 获取Android外部存储-下载类型文件的路径,对应枚举 StorageDirectoryType.downloads

    /// 获取Android外部存储-文档类型文件的路径
    static Future<List<String>> getAndroidDocumentPaths() async =>
        await getAppExternalStoragePaths(type: StorageDirectoryType.documents);
    
  6. 获取Android外部存储-文档类型文件的路径,对应枚举 StorageDirectoryType.documents

    /// 获取Android外部存储-文档类型文件的路径
    static Future<List<String>> getAndroidDocumentPaths() async =>
        await getAppExternalStoragePaths(type: StorageDirectoryType.documents);
    

二、使用案例

PathUtils 的使用也是非常简单,这里分通用、仅Android、仅iOS/macOS 三类来介绍:

1. App通用

调用代码:

// App缓存目录
String appCachePath = await PathUtils.getAppCachePath();
// App支持目录
String appSupportPath = await PathUtils.getAppSupportPath();
// App文档目录
String appDocPath = await PathUtils.getAppDocPath();

运行结果:

// Android
App缓存目录: /data/user/0/com.fitem.flutter_util_code_example/cache
App支持目录: /data/user/0/com.fitem.flutter_util_code_example/files
App文档目录: /data/user/0/com.fitem.flutter_util_code_example/app_flutter

iOS运行结果:

// iOS
App缓存目录: /var/mobile/Containers/Data/Application/AppID/Library/Caches
App支持目录: /var/mobile/Containers/Data/Application/AppID/Library/Application Support
App文档目录: /var/mobile/Containers/Data/Application/AppID/Documents
2. 仅Android

调用代码:

// Android外部存储目录
String androidStoragePath = await PathUtils.getAndroidStoragePath();
// Android外部缓存目录
List<String> androidExternalCachePaths = await PathUtils.getAndroidExternalCachePaths();
// Android图片目录
List<String> androidPicturePaths = await PathUtils.getAndroidPicturePaths();
// Android视频目录
List<String> androidMoviePaths = await PathUtils.getAndroidMoviePaths();
// Android音乐目录
List<String> androidMusicPaths = await PathUtils.getAndroidMusicPaths();
// Android相机目录
List<String> androidDCIMPaths = await PathUtils.getAndroidDCIMPaths();
// Android下载目录
List<String> androidDownloadPaths = await PathUtils.getAndroidDownloadPaths();
// Android文档目录
List<String> androidDocumentPaths = await PathUtils.getAndroidDocumentPaths();

运行结果:

Android外部存储目录: /storage/emulated/0/Android/data/com.fitem.flutter_util_code_example/files
Android外部缓存目录: [/storage/emulated/0/Android/data/com.fitem.flutter_util_code_example/cache]
Android图片目录: [/storage/emulated/0/Android/data/com.fitem.flutter_util_code_example/files/pictures]
Android视频目录: [/storage/emulated/0/Android/data/com.fitem.flutter_util_code_example/files/movies]
Android音乐目录: [/storage/emulated/0/Android/data/com.fitem.flutter_util_code_example/files/music]
Android相机目录: [/storage/emulated/0/Android/data/com.fitem.flutter_util_code_example/files/dcim]
Android下载目录: [/storage/emulated/0/Android/data/com.fitem.flutter_util_code_example/files/downloads]
3. 仅iOS/macOS

调用代码:

// 下载目录 - 仅iOS/macOS
String downloadPath = await PathUtils.getDownloadPath();

运行结果:

下载目录: /var/mobile/Containers/Data/Application/AppID/Downloads

结语

好了,今天的工具类整理文章就到这里,目前插件已发布到 Pub 中,欢迎大家体验。

如果觉得这篇文章对你有所帮助的话,不要忘记一键三连哦,大家的点赞是我更新的动力🥰。

Pub: flutter_util_code

项目源码:FlutterUtilCode

使用案例:Example