我如何使用 ActivityResultLauncher.GetContent() 请求多个 MIME 类型?

问题描述 投票:0回答:4

我正在尝试使用

从用户那里检索一个可以是图像或pdf的文件
registerForActivityResult(ActivityResultContracts.GetContent()) { file: Uri ->
   ......
}.launch(<mimetypes>)

我已经尝试过另一个问题的答案中的

"image/*|application/pdf"
,但它不起作用,有没有办法在使用registerForActivityResult时要求多种MIME类型?

android mime-types
4个回答
5
投票

使用 registerForActivityResult 时有什么方法可以请求多个 MIME 类型吗?

不能直接使用当前版本的

ActivityResultContracts.GetContent
。但是,您应该能够对其进行子类化、覆盖
createIntent()
,并从那里自定义生成的
Intent
。然后,您可以尝试将
EXTRA_MIME_TYPES
添加到该
Intent
以及您想要的其他 MIME 类型的
String[]


5
投票

这是我的示例代码,在 api 31 中测试

var resultGalleryLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            val intent: Intent? = result.data
            if (intent != null) {
                intent.data?.let { selectedImageUri ->
                     ....  
                    }
                }
            } else {
                Timber.e(" >>> error selected image from gallery by intent")
            }
        }
    }


fun galleryLauncher() {
    val intent = Intent(Intent.ACTION_GET_CONTENT, MediaStore.Images.Media.EXTERNAL_CONTENT_URI).apply {
        type = "image/*"
        action = Intent.ACTION_GET_CONTENT
        putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/jpeg", "image/png", "image/jpg"))
        putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)
    }
    resultGalleryLauncher.launch(intent)
}

0
投票

请使用

ActivityResultContracts.OpenMultipleDocuments()
来代替。

import androidx.activity.result.contract.ActivityResultContracts


class DocumentsFragment : Fragment() {

    companion object {

        // 1. List of MIME types
        /**@see <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types">MIME types</a>
         * @see <a href="https://www.iana.org/assignments/media-types/media-types.xhtml">IANA - MIME types</a>*/
        private val MIME_TYPES: Array<String> = arrayOf(
            "image/*", "application/pdf", "application/msword",
            "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
            "application/vnd.oasis.opendocument.text", "text/plain", "text/markdown"
        )
    }
    
    //2. Register for Activity Result callback as class field
    private val getDocuments =
    registerForActivityResult(ActivityResultContracts.OpenMultipleDocuments()/*NOT OpenDocument*/) {
        Log.d("Open documents", "incoming uri: size = ${it.size}")
        add(it)
    }
    
    ...
    //3. set onclick listener
    selectDocumentsButton.setOnClickListener { getDocuments.launch(MIME_TYPES) }
    ...
    
    //4. handle incoming uri list
    private fun add(list: List<Uri>) {
        val setOfFiles = copyToAppDir(list)
        setOfFiles.forEach {
            //TODO: do something            
        }
    }
    
    //5. copy the files to the application folder for further work
    private fun copyToAppDir(list: List<Uri>): Set<File> {
        val set = mutableSetOf<File>()
        list.forEach { uri ->
            try {
                val file: File = copyUriContentToTempFile(uri)
                set.add(file)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        return set
    }
    
    //6. copy selected content by uri
    private fun copyUriContentToTempFile(uri: Uri): File {
        val inputStream = requireContext().contentResolver.openInputStream(uri)
        inputStream.use { input ->
            val tempFile: File = .. ; //TODO: create file
            tempFile.outputStream().use { output ->
                input?.copyTo(output)
            }
            return tempFile
        }
    }
}


0
投票

将建议的解决方案从 Kotlin 翻译为 Java,以防有人需要:

ActivityResultLauncher<Intent> photoPicker2 = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
    if(result.getResultCode() == Activity.RESULT_OK) {
        Intent intent = result.getData();
        if(intent != null) {
            Uri picked = intent.getData();
            if(picked != null) {
                //Process the image...
            }
        }
    }
});

调用启动器:

    try {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"image/jpeg", "image/png", "image/x-png"});
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);
        photoPicker2.launch(intent);
    } catch (ActivityNotFoundException e) {
        try {
            //Fallback to ActivityResultContracts.OpenDocument().
            documentPicker.launch(new String[]{"image/jpeg", "image/png", "image/x-png"});
        } catch (ActivityNotFoundException ignore) {}
    }
© www.soinside.com 2019 - 2024. All rights reserved.