前语

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 渠道上支撑。各渠道支撑的版别如下:

Android iOS Linux macOS Windows
Support SDK 16+ 11.0+ Any 10.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