文件已保存,但在使用ACTION_GET_CONTENT或ACTION_OPEN_DOCUMENT时未显示。

huangapple go评论59阅读模式
英文:

The file is saved but not showing with ACTION_GET_CONTENT or ACTION_OPEN_DOCUMENT

问题

我使用 Retrofit 下载文件并将其保存在下载目录的子文件夹中。当我通过手机的文件管理器检查时,文件已成功下载并保存在以下路径中:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path + "/MyApp"

但是,当我使用 ACTION_GET_CONTENT 或 ACTION_OPEN_DOCUMENT 这样的意图打开文件管理器时,下载的文件不可见。此外,如果我重命名文件或通过手机的文件管理器复制和粘贴文件,一切都会在相同路径中得以修复。

此外,将文件保存在下载文件夹中没有任何问题,但是当创建子文件夹并应该将文件保存在其中时,就会出现这个问题。

通过 DownloadManager 下载没有问题,但我想使用 Retrofit。

下载函数:

suspend fun download(url: String, targetPath: String, progressRetrofit: RetrofitProgress) = flow {
    try {
        val response = apiService.download(url).awaitResponse()
        val body = response.body()
        if (response.isSuccessful && body != null) {
            try {
                val file = File(targetPath)
                body.byteStream().use { inputStream ->
                    FileOutputStream(file).use { outputStream ->
                        val data = ByteArray(1024)
                        var read: Int
                        var currentDownloadSize = 0L
                        val fileSize = body.contentLength()
                        while (inputStream.read(data).also { read = it } != -1) {
                            outputStream.write(data, 0, read)
                            currentDownloadSize += read
                            withContext(Dispatchers.Main) {
                                progressRetrofit.onProgressUpdate((currentDownloadSize * 100 / fileSize).toInt(), fileSize, currentDownloadSize)
                            }
                        }
                        withContext(Dispatchers.Main) {
                            progressRetrofit.onProgressUpdate((currentDownloadSize * 100 / fileSize).toInt(), fileSize, currentDownloadSize)
                        }
                        outputStream.close()
                        outputStream.flush()
                    }
                }
                emit(NetworkResult.Success(true))
            } catch (e: Exception) {
                emit(NetworkResult.Failure(e.message.toString()))
                errorMessage(e.message.toString(), true)
            }
        } else {
            emit(NetworkResult.Failure(response.message()))
            errorMessage(response.errorBody().toString(), true)
        }
    } catch (e: Exception) {
        emit(NetworkResult.Failure(e.message.toString()))
        errorMessage(e.message.toString(), true)
    }
}
英文:

I download a file using Retrofit and save it in a subfolder in the download directory.

when I check with the phone's file manager, it is downloaded and saved correctly. For example, in the following path:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path + "/MyApp"

But when I open the file manager with intent like ACTION_GET_CONTENT or ACTION_OPEN_DOCUMENT the downloaded file is not visible.
In addition, if I rename the file or copy and paste it through the phone's file manager, everything will be fixed in the same path

Also, saving in the downloads folder is done without any problem
But when the subfolder is created and it is supposed to be saved there, this problem occurs

There is no problem with downloading by DownloadManager, but i want use retofit

Download function:

    suspend fun download(url: String, targetPath: String, progressRetrofit: RetrofitProgress) = flow {
    try {
        val response = apiService.download(url).awaitResponse()
        val body = response.body()
        if (response.isSuccessful && body != null) {
            try {
                val file = File(targetPath)
                body.byteStream().use { inputStream ->
                    FileOutputStream(file).use { outputStream ->
                        val data = ByteArray(1024)
                        var read: Int
                        var currentDownloadSize = 0L
                        val fileSize = body.contentLength()
                        while (inputStream.read(data).also { read = it } != -1) {
                            outputStream.write(data, 0, read)
                            currentDownloadSize += read
                            withContext(Dispatchers.Main)
                            {
                                progressRetrofit.onProgressUpdate((currentDownloadSize * 100 / fileSize).toInt(), fileSize, currentDownloadSize)
                            }
                        }
                        withContext(Dispatchers.Main)
                        {
                            progressRetrofit.onProgressUpdate((currentDownloadSize * 100 / fileSize).toInt(), fileSize, currentDownloadSize)
                        }
                        outputStream.close()
                        outputStream.flush()
                    }
                }
                emit(NetworkResult.Success(true))
            } catch (e: Exception) {
                emit(NetworkResult.Failure(e.message.toString()))
                errorMessage(e.message.toString(), true)
            }
        } else {
            emit(NetworkResult.Failure(response.message()))
            errorMessage(response.errorBody().toString(), true)
        }
    } catch (e: Exception) {
        emit(NetworkResult.Failure(e.message.toString()))
        errorMessage(e.message.toString(), true)
    }
}

答案1

得分: 0

自 Android 6.0 版本以来,文件共享行为发生了一系列变化

请查看FileProvider,并进一步查看官方 Android 文档中的 API 变化,例如这个

如果您的代码没有额外的细节,甚至没有可复制的代码示例,我无法提供更多帮助。

英文:

Since Android 6.0 there are bunch of changes in file sharing behaviour.

Please take a look on FileProvider and look further through API changes in the official android documentation, e.g. like this.

Without extra details in your code or even reproducible code sample I can not help more.

答案2

得分: 0

你是对的,如果用户直接使用“下载”项进行操作_OPEN_DOCUMENT,就会出现这种情况。而用户应该浏览设备,进入“Download”目录,然后再进入子目录。

(注意:第一个以s结尾,真正的目录是没有s的。)

经过更多的测试,发现如果文件被MediaStore扫描了,就会出现这种情况。所以在下载后添加一些代码行来让它被扫描。

英文:

Hmmmm...

You are right...

It happens.

But only if with ACTION_OPEN_DOCUMENT the user directly uses the Downloads item.

Instead the user should browse the device, and go to Download directory and then to the subdirectory.

(Note: The first ends with an s, the real directory is without s.).

After some more tests it appeared if the file was scanned by the MediaStore.

So add some few lines of code to let it be scanned after download.

huangapple
  • 本文由 发表于 2023年2月6日 15:54:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75358627.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定