前言
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 插件,专门用来获取不同平台的文件路径。
官方出品,必属精品
。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 枚举类对应类型如下:
-
获取Android外部存储-图片类型文件的路径,对应枚举
StorageDirectoryType.pictures
。/// 获取Android外部存储-图片类型文件的路径 static Future<List<String>> getAndroidPicturePaths() async => await getAppExternalStoragePaths(type: StorageDirectoryType.pictures);
-
获取Android外部存储-视频类型文件的路径,对应枚举
StorageDirectoryType.movies
。/// 获取Android外部存储-视频类型文件的路径 static Future<List<String>> getAndroidMoviePaths() async => await getAppExternalStoragePaths(type: StorageDirectoryType.movies);
-
获取Android外部存储-音频类型文件的路径,对应枚举
StorageDirectoryType.music
。/// 获取Android外部存储-音频类型文件的路径 static Future<List<String>> getAndroidMusicPaths() async => await getAppExternalStoragePaths(type: StorageDirectoryType.music);
-
获取Android外部存储-相机目录下的文件的路径,对应枚举
StorageDirectoryType.dcim
。/// 获取Android外部存储-相机目录下的文件的路径 static Future<List<String>> getAndroidDCIMPaths() async => await getAppExternalStoragePaths(type: StorageDirectoryType.dcim);
-
获取Android外部存储-下载类型文件的路径,对应枚举
StorageDirectoryType.downloads
。/// 获取Android外部存储-文档类型文件的路径 static Future<List<String>> getAndroidDocumentPaths() async => await getAppExternalStoragePaths(type: StorageDirectoryType.documents);
-
获取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