为什么android:requestLegacyExternalStorage=";“真的”;不适用于Android 10-API 29

为什么android:requestLegacyExternalStorage=";“真的”;不适用于Android 10-API 29,android,android-10.0,scoped-storage,Android,Android 10.0,Scoped Storage,我已经将我的project compileSdkVersion从28迁移到29,并在清单中添加了android:requestLegacyExternalStorage=“true”,但下载和打开文件等文件操作与SDK 28中的操作不同 渐变文件 清单文件 路径应为内部存储“/myapp/study materials/”中的文件夹位置 url应该是来自服务器的文件位置url 打开文件 路径应为内部存储“/myapp/study materials/”中的文件夹位置 title应该是文件名

我已经将我的project compileSdkVersion从28迁移到29,并在清单中添加了android:requestLegacyExternalStorage=“true”,但下载和打开文件等文件操作与SDK 28中的操作不同

渐变文件

清单文件

  • 路径应为内部存储“/myapp/study materials/”中的文件夹位置
  • url应该是来自服务器的文件位置url
打开文件

  • 路径应为内部存储“/myapp/study materials/”中的文件夹位置
  • title应该是文件名

我已经添加了所有在更新到SDK 29时不起作用的代码,我想从服务器下载一个文件并将其保存到内部存储中特定于应用程序的文件夹中。下载之前,还需要检查该文件是否已下载。如果已经下载了,我需要打开该文件

我遇到了与这里提到的类似的问题。我发现在安卓10上,我必须检查
写外部存储
,即使文件已经下载,我只需要打开它

if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, arrayOf(WRITE_EXTERNAL_STORAGE), 100)
}
在对文件进行任何操作之前添加检查修复了打开APK文件时出现的“解析包时出现问题”错误

编辑:

我还找到了另一个(可能更好的)解决方案。我没有使用外部公共存储,而是切换到应用程序的外部存储:

downloadRequest.setDestinationInExternalFilesDir(...)
并使用

new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), mFileName);

而不是
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY\u下载)


作为奖励,无需在AndroidManifest中使用android:requestLegacyExternalStorage=“true”。

您能描述一下什么不起作用吗?当您通过应用程序提供传统存储(如truefile下载、文件存在性检查和文件打开)时,它的工作原理应该与以前完全相同。下载与是否请求传统外部存储无关。因此,您可以解释一下您的意思。此外,没有代码尝试检查文件的存在或尝试打开文件。在android 10和11中,您处理文件的最佳朋友是文件uri
downloadManager.enqueue()
返回下载id,您可以通过
downloadManager.geturifordownloaddedfile(downloaddid)
fun openFile(title: String, path: String){
    try {
        val newFile = File(Environment.getExternalStorageDirectory().absolutePath + path, title)

        val uri = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M)
        {
            FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileprovider", newFile)
        } else{
            Uri.fromFile(newFile)
        }

        val intent = Intent(Intent.ACTION_VIEW, uri)
        intent.setDataAndType(uri, context.contentResolver.getType(uri))
        intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        val activities: List<ResolveInfo> = context.packageManager.queryIntentActivities(intent, 0)
        val isIntentSafe: Boolean = activities.isNotEmpty()

        // Start an activity if it's safe
        if (isIntentSafe) {
            context.startActivity(Intent.createChooser(intent, "Open With"))
        } else{
            MDToast.makeText(context, "No Application Found For Opening This File", MDToast.TYPE_INFO).show()
        }
    } catch (e : Exception){
        println("=============== ${e.message}")
    }

}
override fun checkFileExistence(title: String, path: String): Boolean {
    var flag = false
    try {
        val direct = File(
            Environment.getExternalStorageDirectory().toString()
                    + path + title)
        flag = direct.exists()
    } catch (e: Exception) {
    }

    return flag
}
if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, arrayOf(WRITE_EXTERNAL_STORAGE), 100)
}
downloadRequest.setDestinationInExternalFilesDir(...)
new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), mFileName);