GXSZone
建议单独出一个库(如果有时间),毕竟版本适配对于小白各个方面不是很周到,需要一个傻瓜式的,可以按照file的api命名编写,无需其他使用成本,直接过渡,库内判断android版本,对于增删改查,移动复制删除,一条命令自动对应当前android版本执行适用于当前系统版本的命令,使用者只需按照之前的File的api使用,库内直接封装好各个版本的适配api
#23 · closed · 24 comments
建议单独出一个库(如果有时间),毕竟版本适配对于小白各个方面不是很周到,需要一个傻瓜式的,可以按照file的api命名编写,无需其他使用成本,直接过渡,库内判断android版本,对于增删改查,移动复制删除,一条命令自动对应当前android版本执行适用于当前系统版本的命令,使用者只需按照之前的File的api使用,库内直接封装好各个版本的适配api
是因为 [分区存储](https://developer.android.google.cn/training/data-storage#scoped-storage) 需要适配使用吗?
@afkT 对的
对于每个版本都需要单独适配,能将这些适配在库里统一处理,使用者只需像之前一样简单的使用就好了
其实是有的,需要依赖 ```gradle // DevApp Android 工具类库 implementation 'io.github.afkt:DevAppX:2.2.8' // DevAssist 快捷功能辅助类库 implementation 'io.github.afkt:DevAssist:1.2.5' ``` [DevAssist Engine](https://github.com/afkT/DevUtils/blob/master/lib/DevOther/src/main/java/ktx/dev/engine) DevAssist Engine 主要为了解决项目代码中<span style="color:red;">**对第三方框架强依赖使用、以及部分功能版本适配。**</span>通过实现对应功能模块 Engine 接口,实现对应的方法功能,<span style="color:blue;">**对外无需关注实现代码,直接通过 DevXXXEngine 进行调用,**</span><span style="color:red;">**实现对第三方框架解耦、一键替换第三方库、同类库多 Engine 混合使用、以及部分功能适配 ( 如外部文件存储 MediaStore 全局适配 ) 等**</span> 但是对应的 Engine 实现代码,需要 copy 到项目中进行初始化。 [Java 代码实现](https://github.com/afkT/DevUtils/tree/master/lib/DevOther/src/main/java/dev/engine) [Kotlin 代码实现](https://github.com/afkT/DevUtils/tree/master/lib/DevOther/src/main/java/dev/engine)
你需要的存储适配,在以上路径的 storage 包内,根据你使用的语言,copy 到项目中 ```java // Application 中初始化 DevStorageEngine.setEngine(DevMediaStoreEngineImpl()) ``` ```java // 使用 DevStorageEngine.getEngine().xxx ``` * **DevUtils MediaStore Engine 实现 ->** [DevMediaStoreEngineImpl.java](https://github.com/afkT/DevUtils/blob/master/lib/DevOther/src/main/java/dev/engine/storage/DevMediaStoreEngineImpl.java) | 方法 | 注释 | | :- | :- | | insertImageToExternal | 插入一张图片到外部存储空间 ( SDCard ) | | insertVideoToExternal | 插入一条视频到外部存储空间 ( SDCard ) | | insertAudioToExternal | 插入一条音频到外部存储空间 ( SDCard ) | | insertDownloadToExternal | 插入一条文件资源到外部存储空间 ( SDCard ) | | insertMediaToExternal | 插入一条多媒体资源到外部存储空间 ( SDCard ) | | insertImageToInternal | 插入一张图片到内部存储空间 | | insertVideoToInternal | 插入一条视频到内部存储空间 | | insertAudioToInternal | 插入一条音频到内部存储空间 | | insertDownloadToInternal | 插入一条文件资源到内部存储空间 | | insertMediaToInternal | 插入一条多媒体资源到内部存储空间 |
这个 DevMediaStoreEngineImpl 模块,就是用于处理对 内部存储、外部存储(Image、Video、Audio、Download)文件不同操作,至于移动、复制文件等,应该都在内部存储路径中操作,无需适配
@afkT 移动、复制文件等是在外部存储操作,因为存储的都是重要文件放在外部备份比较安全,对于使用外部存储的场景还是不少的
库的精华就在于对外部存储的适配,haha...
按我的理解,你要的移动、复制文件,其实就是把文件备份到外部存储去是吗,(因为分区存储原因,你高版本是无法移动文件,只能说存入文件)
按我的理解,你要的移动、复制文件,其实就是把文件备份到外部存储去是吗,(因为分区存储原因,你高版本是无法移动文件,只能说存入文件)
对
DevStorageEngine 就有这个方法 ```kotlin DevStorageEngine.getEngine()?.insertMediaToExternal( // 外部文件存储信息, 会根据文件后缀,自动获取 mimeType 存储到对应文件夹下 StorageItem.createExternalItem( "recy.jpg" ), // 资源信息, 如 byte[]、Bitmap、Drawable、Uri、FilePath、InputStream 等 DevSource.create() // 存储结果回调 object : OnDevInsertListener { override fun onResult( result: StorageResult, params: StorageItem?, source: DevSource? ) { showToast( result.isSuccess(), "保存成功\n${FileUtils.getAbsolutePath(result.getFile())}", "保存失败" ) } } ) ```
关于外部文件存储信息创建有三种方式: ```kotlin // 外部文件存储信息, 会根据文件后缀,自动获取 mimeType 存储到对应文件夹下 StorageItem.createExternalItem( "recy.jpg" ) // 自己指定 mimeType StorageItem.createExternalItem( "recy", MediaStoreUtils.MIME_TYPE_IMAGE_JPG ) // 自己指定 mimeType 并且存储到对应文件夹下 StorageItem.createExternalItem( "recy", MediaStoreUtils.MIME_TYPE_IMAGE_JPG, MediaStoreUtils.RELATIVE_IMAGE_PATH ) ```
我首页看了下有存储的api就有了独立存储库的想法,本人小白一个,不会封装,还是感谢花费时间给我解答
其实你要的,都在 [DevMediaStoreEngineImpl.java](https://github.com/afkT/DevUtils/blob/master/lib/DevOther/src/main/java/dev/engine/storage/DevMediaStoreEngineImpl.java) 这里,帮你实现好了。只是没有放到库里面,因为每个项目可能需求不同,在存储前、存储后都有各自的操作等,为了方便,就提供代码,直接 copy 进行使用、修改,但是核心适配功能,已经是都完成的。
好的,我在看下
@afkT 作者你好,请问DevMediaStoreEngineImpl.java这个类只有保存文件,那么如何根据文件名字名查询保存地址的uri?
> @afkT 作者你好,请问DevMediaStoreEngineImpl.java这个类只有保存文件,那么如何根据文件名字名查询保存地址的uri? 有的,不过是通过`已保存文件的完整路径`获取所属的 Uri [UriUtils.getMediaUri(File)](https://github.com/afkT/DevUtils/blob/master/lib/DevApp/src/main/java/dev/utils/app/UriUtils.java#L233) 该 API 功能适配,我已封装在 [DevEngine](https://github.com/afkT/DevUtils/blob/master/lib/DevEngine/README.md) 库中了,可以视情况依赖使用
完整路径要怎么获取?比如有这样的场景:在某个页面保存了一个文件到公共目录,第二次进入该页面,需要判断该文件是否存在,那么这个时候需要怎么获取到您这边所说的完整路径?
> 完整路径要怎么获取?比如有这样的场景:在某个页面保存了一个文件到公共目录,第二次进入该页面,需要判断该文件是否存在,那么这个时候需要怎么获取到您这边所说的完整路径? ```kotlin // 待保存文件名 val fileName = "asd.jpg" // 创建存储参数数据模型 val item = StorageItem.createExternalItem(fileName) // 判断待保存文件是否存在 val exist = UriUtils.isUriExists( UriUtils.getUriForFile(item?.getExternalFile(fileName)) ) ``` 这样就可以复合你要求了,如果文件不存在,那么调用 `DevEngine.getStorage()?.insertImageToExternal()` 传入上面的 item 进行存储
完整 code ```kotlin // 待保存文件名 val fileName = "asd.jpg" // 创建存储参数数据模型 val item = StorageItem.createExternalItem(fileName) // 判断待保存文件是否存在 val exist = UriUtils.isUriExists( UriUtils.getUriForFile(item?.getExternalFile(fileName)) ) // 判断文件是否存在 if (exist) { ToastTintUtils.success("$fileName 文件已存在") } else { DevEngine.getStorage()?.insertImageToExternal( item, // 存储参数数据模型 DevSource.create(wallpaper), // 待存储数据源 object : OnDevInsertListener { override fun onResult( result: StorageResult, params: StorageItem?, source: DevSource? ) { showToast( result.isSuccess(), "保存成功\n${FileUtils.getAbsolutePath(result.getFile())}", "保存失败" ) } } ) } ```
感谢回复,大概流程了解。希望能把版本适配这块单独抽出来,项目写的非常好,但是有点大而乱了。我相信该issue提出者,也是看demo,好多东西没有找到的原因,只能过来请教。
> 感谢回复,大概流程了解。希望能把版本适配这块单独抽出来,项目写的非常好,但是有点大而乱了。我相信该issue提出者,也是看demo,好多东西没有找到的原因,只能过来请教。 哈哈,有的,就是因为这个 issue 专门封装了一个库 [DevEngine](https://github.com/afkT/DevUtils/blob/master/lib/DevEngine/README.md) 库,这个库包含大多数快捷开发的功能,而不是像以前需要自己 copy 代码进行使用。
error: resource android:color/system_neutral2_500 not found 为啥引入抓包工具就包这个错误