如何在 jetpack compose 中通过键盘接收 GIF?

mam*_*ama 6 android mime-types kotlin android-jetpack-compose

我正在尝试在 jetpack compose 中进行聊天,并且希望能够使用三星上的标准 gif 键盘发送 gif。

当我在普通文本字段上单击 GIF 时,我当前收到一条消息“无法在此处输入此内容”

我发现了一个叫做Commit Content API的东西,它应该可以在旧的 EditText 中添加 GIF,所以我在 AndroidView 中尝试,现在我不再收到错误消息,但我也不知道 GIF 在哪里是什么以及它是如何表示的。

AndroidView(factory = {
    val editText = @SuppressLint("AppCompatCustomView")
    object : EditText(it) {

        override fun setOnReceiveContentListener(
            mimeTypes: Array<out String>?,
            listener: OnReceiveContentListener?
        ) {
            super.setOnReceiveContentListener(mimeTypes, listener)
        }


        override fun onCreateInputConnection(editorInfo: EditorInfo): InputConnection {
            val ic: InputConnection = super.onCreateInputConnection(editorInfo)
            EditorInfoCompat.setContentMimeTypes(editorInfo, arrayOf("image/gif"))

            val callback =
                InputConnectionCompat.OnCommitContentListener { inputContentInfo, _, _ ->
                    try {
                        inputContentInfo.requestPermission()
                    } catch (e: Exception) {
                        return@OnCommitContentListener false
                    }
                    true  // return true if succeeded
                }
            return InputConnectionCompat.createWrapper(ic, editorInfo, callback)
        }
    }
    editText
}) {}
Run Code Online (Sandbox Code Playgroud)

Phi*_*hov 5

callback每次选择 GIF 时都会调用。您可以从以下位置获取 URI inputContentInfo

val callback =
    InputConnectionCompat.OnCommitContentListener { inputContentInfo, _, _ ->
        try {
            inputContentInfo.requestPermission()
        } catch (e: Exception) {
            return@OnCommitContentListener false
        }
        gifUri = inputContentInfo.contentUri
        true  // return true if succeeded
    }
Run Code Online (Sandbox Code Playgroud)

完美的是,您应该将文件从这个 URI 复制到您自己的存储中并调用inputContentInfo.releasePermission(),因为contentUri它将在某个时候被释放。更多信息可以在文档中找到。

您可以使用 Coil 显示此 URI 的内容,如本答案所示。注意需要添加依赖io.coil-kt:coil-gif:$coil_version

一个完整的工作示例:

var gifUri by remember { mutableStateOf<Uri?>(null) }
val context = LocalContext.current
Image(
    rememberImagePainter(
        gifUri,
        imageLoader = remember {
            ImageLoader(context).newBuilder()
                .componentRegistry {
                    if (SDK_INT >= 28) {
                        add(ImageDecoderDecoder(context))
                    } else {
                        add(GifDecoder())
                    }
                }.build()
        }
    ),
    contentDescription = null,
    modifier = Modifier.size(300.dp)
)

AndroidView(factory = { context ->
    val editText = @SuppressLint("AppCompatCustomView")
    object : EditText(context) {

        override fun setOnReceiveContentListener(
            mimeTypes: Array<out String>?,
            listener: OnReceiveContentListener?
        ) {
            super.setOnReceiveContentListener(mimeTypes, listener)
        }


        override fun onCreateInputConnection(editorInfo: EditorInfo): InputConnection {
            val ic: InputConnection = super.onCreateInputConnection(editorInfo)
            EditorInfoCompat.setContentMimeTypes(editorInfo, arrayOf("image/gif"))

            val callback =
                InputConnectionCompat.OnCommitContentListener { inputContentInfo, _, _ ->
                    try {
                        inputContentInfo.requestPermission()
                    } catch (e: Exception) {
                        return@OnCommitContentListener false
                    }
                    gifUri = inputContentInfo.contentUri
                    true  // return true if succeeded
                }
            return InputConnectionCompat.createWrapper(ic, editorInfo, callback)
        }
    }
    editText
}) {}
Run Code Online (Sandbox Code Playgroud)