FileOperator icon indicating copy to clipboard operation
FileOperator copied to clipboard

🔥 【置顶】获取路径为空的问题(Path return null problem)

Open javakam opened this issue 2 years ago • 10 comments

✨基本上每一个issue都会提到的问题👉Android Q及以上版本获取路径为空

🌴测试环境 API 30 , Android 11.0

https://user-images.githubusercontent.com/15343661/132307433-c4cde301-d9b5-4bc9-b460-fcb70db4dbcb.mp4

🍎 可以看到, 同一文件会有两种不同的 Uri :

  1. 从侧边栏手机图标进入时获取到文件的Uricontent://com.android.externalstorage.documents/...,此时路径不为空;
  2. 从侧边栏Download进入时Uricontent://com.android.providers.downloads/..., 此时路径为空。

🌴建议使用Uri替换Path, 如上传文件操作可以使用ContentResolver.openInputStream/openFile/...等API操作, 唯一缺点是不能显示文件路径, 但不会影响功能使用。

javakam avatar Sep 07 '21 08:09 javakam

这个问题现在解决了吗

yykou avatar Sep 24 '21 01:09 yykou

这个问题现在解决了吗

这个是Android 新版本的特性, 目前没有好的替代方式

javakam avatar Sep 24 '21 06:09 javakam

android11系统,下载目录根据uri获取path,我目前用了以下方式获取 // DownloadsProvider else if (isDownloadsDocument(uri)) {

            // TODO 下载目录中选择或者新建文件夹,在文件夹中存储文件
            final String id = DocumentsContract.getDocumentId(uri);
            if (id != null && id.startsWith("raw:")) {
                return id.substring(4);
            }

            // TODO 下载根目录存储文件
            String displayName = DocumentFile.fromSingleUri(context, uri).getName();
            return Environment.getExternalStorageDirectory().toString()
                    + File.separator + "Download" + File.separator + displayName;

        }

不知道这种获取有什么弊端没

yykou avatar Sep 24 '21 07:09 yykou

android11系统,下载目录根据uri获取path,我目前用了以下方式获取 // DownloadsProvider else if (isDownloadsDocument(uri)) {

            // TODO 下载目录中选择或者新建文件夹,在文件夹中存储文件
            final String id = DocumentsContract.getDocumentId(uri);
            if (id != null && id.startsWith("raw:")) {
                return id.substring(4);
            }

            // TODO 下载根目录存储文件
            String displayName = DocumentFile.fromSingleUri(context, uri).getName();
            return Environment.getExternalStorageDirectory().toString()
                    + File.separator + "Download" + File.separator + displayName;

        }

不知道这种获取有什么弊端没

试了下, 拼接路径不靠谱啊... 路径不是固定的Environment.getExternalStorageDirectory().toString()+ File.separator + "Download" + File.separator + displayName

javakam avatar Sep 27 '21 03:09 javakam

Download 路径下可以使用这种,但是android11 用以下这种方式获取更靠谱: final String id = DocumentsContract.getDocumentId(uri); if (id != null && id.startsWith("raw:")) { return id.substring(4); } String displayName = DocumentFile.fromSingleUri(context, uri).getName(); return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + displayName;

yykou avatar Oct 11 '21 06:10 yykou

图片压缩的时候,传入 Uri ,会有部分图片返回的 Uri 为空,这个问题要怎么解决

Payaml avatar Nov 03 '21 00:11 Payaml

图片压缩的时候,传入 Uri ,会有部分图片返回的 Uri 为空,这个问题要怎么解决

  1. 先检测下传入的图片Uri是否正确, 参考方法 fun checkUri(uri: Uri?): Boolean {...}

https://github.com/javakam/FileOperator/blob/master/library_core/src/main/java/ando/file/core/FileUtils.kt

  1. 如果传入的Uri没问题, 可以试试屏蔽掉setRenameListener

image

  1. [推荐]如果只是单图片处理, 建议压缩图片别缓存, 比如做图片上传可以使用ByteArrayOutputStream

参考方法👉 fun compressPure(uri: Uri?, maxSize: Long = 300L): Bitmap? {...}

https://github.com/javakam/FileOperator/blob/master/library_compressor/src/main/java/ando/file/compressor/ImageCompressEngine.kt

javakam avatar Nov 05 '21 02:11 javakam

可以看下这篇文章 Android通过uri获取文件路径 把URI对应的拷到沙盒里面去

wsdydeni avatar Jan 13 '22 07:01 wsdydeni

可以看下这篇文章 Android通过uri获取文件路径 把URI对应的拷到沙盒里面去

他的解决方式是把读取不到路径的文件复制到可以读取路径的目录中, 这种方式大概在 v1.3.7 版本时也是有的。可以参照 #21 中的解释:

image

和上面原理相同的还有另外一种方式: https://github.com/coltoscosmin/FileUtils/blob/master/FileUtils.java 也可以解决路径为空的问题:

image

之所以后面删掉这种方式是因为它对于处理小文件和少量文件时还可以, 一旦文件过大或数量多的话就会严重占用手机存储, 所以建议尽量用uri操作文件而不是直接使用path。 当然万不得已的情况下不失为一种解决方式。 image

javakam avatar Jan 14 '22 02:01 javakam

可以看下这篇文章 Android通过uri获取文件路径 把URI对应的拷到沙盒里面去

他的解决方式是把读取不到路径的文件复制到可以读取路径的目录中, 这种方式大概在 v1.3.7 版本时也是有的。可以参照 #21 中的解释:

image

和上面原理相同的还有另外一种方式: coltoscosmin/FileUtils@master/FileUtils.java 也可以解决路径为空的问题:

image

之所以后面删掉这种方式是因为它对于处理小文件和少量文件时还可以, 一旦文件过大或数量多的话就会严重占用手机存储, 所以建议尽量用uri操作文件而不是直接使用path。 当然万不得已的情况下不失为一种解决方式。 image

我现在的场景就是必须得获取到真实路径,单从不能出问题的角度来看,这个方法不失为暂时的解决之策。还有就是那个 FileSelector的构建能不能改改啊,以及示范例子给多点,点进去看源码才知道,还要处理回调。。。

wsdydeni avatar Jan 14 '22 03:01 wsdydeni