file://scheme 和 content://scheme 混淆 || 安卓

Zae*_*tar 5 android android-intent android-contentprovider

随着 android 不断提高其安全性并不断改变一些东西,以使 Android 操作系统对漏洞更安全,因此了解开发人员进入它的新结构是一件好事。最近几年我一直在远离开发。我只是注意到一些东西已经改变,例如 URI 的文件方案。

案例 1 ::我正在使用下面提到的自定义 URI 启动相机意图。

var takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(packageManager) != null) {
        // Create the File where the photo should go
        var photoFile: File? = null
        try {
            photoFile = createImageFile()
        } catch (ex: IOException) {
            // Error occurred while creating the File
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            val photoURI: Uri = FileProvider.getUriForFile(this,
                    BuildConfig.APPLICATION_ID + ".fileprovider",
                    photoFile)
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO)
        }
    }
Run Code Online (Sandbox Code Playgroud)

photoURI 是自定义 URI。当我拍照并检查 URI 时,它有 file:// 开始,我可以从那里获取文件路径,我可以用它做一些事情(我正在将它上传到服务器)

案例二

我正在启动从图库中选择图像的简单意图

        val intent = Intent()
    intent.type = "image/*"
    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
    intent.action = Intent.ACTION_GET_CONTENT
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), TYPE_IMAGE)
Run Code Online (Sandbox Code Playgroud)

现在,当我选择图像并检查 URI 时,它的 start 中有 content://。当我尝试从中获取文件路径时,麻烦就开始了。我一直在搜索 SOF,但没有一个解决方案对我有用。

我获取文件路径的主要目的是我想从设备中选择文件并将其上传到服务器。但是使用 content:// 方案我无法从 URI 制作文件,因此无法发送此文件服务器。

我刚刚阅读了有关方案系统的CommonsWareBlog。它清除了一些东西,但我仍然不知道如何在我的 onActivityResult 中从 content:// too file:// 切换!

我想再次提及,目前关于 SOF 的答案对我不起作用,这就是为什么我必须详细询问这个问题。

我正在使用 7.0 设备模拟器

这只是我在实际中遇到的问题的一个示例,我正在获取 PDF 和 DOCX 文件并希望将它们上传到服务器上,在选择文件后,我的 URI 带有 content:// 方案,但我无法创建文件并发送到服务器。

我不确定我对计划的遗漏。我希望这个问题能帮助许多其他不熟悉文件系统的开发人员。

很高兴尝试根据我从意图中选择文件的问题通过代码示例进行解释(如果您愿意)

Paw*_*wel 5

从 Android 7.0 开始,file://不鼓励返回方案(android changelog),因为它可能会泄漏私人文件夹中的文件。您仍然可能会遇到它,特别是在使用目标为牛轧糖以下的应用程序时。

简短的答案是,当您查询Intent.ACTION_GET_CONTENTYou receive content://uri 时,您可以在ContentResolver.openInputStream(Uri)上获取数据。这可确保您选择的项目是只读的,并掩盖其真实来源 - 它可能是一个文件,远程提供或由提供商一起生成。