Android Input Connection Error

Android input connection error

Such problems occur when the input connection in the previous page(or class) has not been closed. Check whether you've closed the input connection in the previous class
(by giving connection.close()).

because currentInputConnection always returns null

You are getting NullPointerException on the second line of the following code:

val focusedTextField = currentInputConnection
focusedTextField.commitText(text, newCursorPosition)

because the currently active InputConnection isn't bound to the input method, and that's why currentInputConnection is null.

There is a onBindInput method in InputConnection, which is called when a new client has bound to the input method. Upon this call you know that currentInputConnection return valid object.
So before using currentInputConnection client should be bound to the input method.

To use IMEService's public methods outside of its class scope, you need to have an instance of the bound service. Digging into your sources on GitHub it seems the problem is easy to solve by passing IMEService to the TestKey() function. The whole code will look something like this:

@Composable
fun TestKey(modifier: Modifier = Modifier, connection: IMEService) {
Key(
modifier = modifier
//...
.clickable {
connection.sendText(unicodeToString(0x1F383), 1)
}
) {
Icon(/*...*/)
}
}

@Composable
fun EmojiLayout(navController: NavHostController, connection: IMEService) {

val (currentPage, onPageChange) = remember {
mutableStateOf(EmoticonsAndEmotionsPage)
}

Column(modifier = Modifier.fillMaxSize()) {
EmojiPage(
//...
)
Row(
//...
) {
//...
TestKey(Modifier.weight(1f), connection)
}
}
}

@Composable
fun KeyboardScreen(connection: IMEService) {

AmazingKeyboardTheme() {
Column(
//...
) {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "qwertyLayout") {
//...
composable("emojiLayout") { EmojiLayout(navController, connection) }
}
}
}
}

class AndroidKeyboardView(context: Context) : FrameLayout(context) {

constructor(service: IMEService) : this(service as Context) {
inflate(service, R.layout.keyboard_view, this)
findViewById<ComposeView>(R.id.compose_view).setContent {
KeyboardScreen(connection = service)
}
}
}

IMEService class stays the same.

Android: What is an InputConnectionWrapper and what does it do?

InputConnectionWrapper class is a helper class or a class built using InputConnection class. Where the use of InputConnection class is

The InputConnection interface is the communication channel from an InputMethod back to the application that is receiving its input. It is used to perform such things as reading text around the cursor, committing text to the text box, and sending raw key events to the application.

Which means that we can read/perform operations from an input view from different scenario's.
For example: getTextAfterCursor method helps to obtain the text after the cursor.

sendKeyEvent method is to send a key event to the input view, like backpress, return etc.



Related Topics



Leave a reply



Submit