The snippet below is a custom view that enables keyboard like GBoard to enter GIFs and stickers.
When the user enters a GIF, you’ll get a content-uri that you can use to upload the GIF to your backend.
Assuming et_message
is a GifEditText
in your layout, you can use the snippet below like this:
et_message.keyBoardInputCallbackListener = object : KeyBoardInputCallbackListener {
override fun onCommitContent(
inputContentInfo: InputContentInfoCompat?,
flags: Int,
opts: Bundle?
) {
inputContentInfo?.let { info ->
val mime = info.description.getMimeType(0)
val contentUri = info.contentUri
// TODO upload the contentUri
// TODO show a preview (pass contentUri into Glide)
}
}
}
GifEditText.kt
package com.pixplicity.example
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.util.AttributeSet
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
import androidx.appcompat.widget.AppCompatEditText
import androidx.core.view.inputmethod.EditorInfoCompat
import androidx.core.view.inputmethod.InputConnectionCompat
import androidx.core.view.inputmethod.InputContentInfoCompat
import com.pixplicity.example.R
interface KeyBoardInputCallbackListener {
fun onCommitContent(
inputContentInfo: InputContentInfoCompat?,
flags: Int,
opts: Bundle?
)
}
class GifEditText : AppCompatEditText {
var imgTypeString = arrayOf(
"image/png",
"image/gif",
"image/jpeg",
"image/webp"
)
var keyBoardInputCallbackListener: KeyBoardInputCallbackListener? = null
constructor(context: Context) : this(context, null, 0)
constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(
context,
attrs,
R.attr.editTextStyle
)
override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? {
val ic = super.onCreateInputConnection(outAttrs)
EditorInfoCompat.setContentMimeTypes(
outAttrs,
imgTypeString
)
return InputConnectionCompat.createWrapper(ic, outAttrs, callback)
}
val callback: InputConnectionCompat.OnCommitContentListener =
object : InputConnectionCompat.OnCommitContentListener {
override fun onCommitContent(
inputContentInfo: InputContentInfoCompat,
flags: Int,
opts: Bundle?
): Boolean {
// read and display inputContentInfo asynchronously
val f = flags and InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION
if (Build.VERSION.SDK_INT >= 25 && f != 0) {
try {
inputContentInfo.requestPermission()
} catch (e: Exception) {
return false
}
}
var supported = false
for (mimeType in imgTypeString) {
if (inputContentInfo.description.hasMimeType(mimeType)) {
supported = true
break
}
}
if (!supported) {
return false
}
keyBoardInputCallbackListener?.onCommitContent(inputContentInfo, flags, opts)
return true
}
}
}