I made this "custom keyboard" by following the wonderful outline in this link AND NOT USING ECLIPSE. I used Android Studio (AS) 1.1.0.
Here's a screenshot from my device:
The only problem is that the procedure requires changing settings for Language and Input
AND ALSO replaces the keyboard FOR ALL APPS. I don't want that. I just want MY app to change the keyboard for ITSELF and then revert to the previous keyboard as soon as my app goes off screen, otherwise I'm going to be a huge pain in users' butts. Rather than do that, I may as well just add buttons to perform the keypresses I hoped to invoke via a custom keyboard. (It's not gruesome; user just has to pull down the notification bar and select choose input method, but still too intrusive for most users.)
Here's the structure:
The keypad is altered in qwerty.xml
by doing lots of this:
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="60dp"
>
<Row>
<Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
<Key android:codes="50" android:keyLabel="2"/>
<Key android:codes="51" android:keyLabel="3"/>
<Key android:codes="52" android:keyLabel="4"/>
<Key android:codes="53" android:keyLabel="5"/>
<Key android:codes="54" android:keyLabel="6"/>
<Key android:codes="55" android:keyLabel="7"/>
<Key android:codes="56" android:keyLabel="8"/>
<Key android:codes="57" android:keyLabel="9"/>
<Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
</Row>
...
Here's method.xml
:
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
<subtype
android:label= "@string/subtype_en_US"
android:imeSubtypeLocale= "en_US"
android:imeSubtypeMode= "keyboard"
/>
</input-method>
Here's AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dslomer64.simplekeyboard">
<application
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:theme="@style/AppTheme">
<service android:name=".SimpleIME"
android:label="@string/simple_ime"
android:permission="android.permission.BIND_INPUT_METHOD"
>
<meta-data android:name="android.view.im" android:resource="@xml/method"/>
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
</service>
</application>
</manifest>
The service
that's added to the manifest is what gets at the soft keyboard through the code in SimpleIME.java
(empty overrides omitted):
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.media.AudioManager;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputConnection;
public class SimpleIME extends InputMethodService
implements KeyboardView.OnKeyboardActionListener
{
private KeyboardView kv;
private Keyboard keyboard;
private boolean caps = false;
@Override
public View onCreateInputView() {
kv = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard, null);
keyboard = new Keyboard(this, R.xml.qwerty);
kv.setKeyboard(keyboard);
kv.setOnKeyboardActionListener(this);
return kv;
}
private void playClick(int keyCode){
AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);
switch(keyCode){
case 32:
am.playSoundEffect(AudioManager.FX_KEYPRESS_SPACEBAR);
break;
case Keyboard.KEYCODE_DONE:
case 10:
am.playSoundEffect(AudioManager.FX_KEYPRESS_RETURN);
break;
case Keyboard.KEYCODE_DELETE:
am.playSoundEffect(AudioManager.FX_KEYPRESS_DELETE);
break;
default: am.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD);
}
}
@Override
public void onKey(int primaryCode, int[] keyCodes) {
InputConnection ic = getCurrentInputConnection();
playClick(primaryCode);
switch(primaryCode){
case Keyboard.KEYCODE_DELETE :
ic.deleteSurroundingText(1, 0);
break;
case Keyboard.KEYCODE_SHIFT:
caps = !caps;
keyboard.setShifted(caps);
kv.invalidateAllKeys();
break;
case Keyboard.KEYCODE_DONE:
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
break;
default:
char code = (char)primaryCode;
if(Character.isLetter(code) && caps){
code = Character.toUpperCase(code);
}
ic.commitText(String.valueOf(code),1);
}
}
...
}
I wonder if anyone out there has done what I need: implement a custom keyboard JUST FOR ONE APP and restore original upon loss of screen focus.
I just want MY app to change the keyboard for ITSELF
That is not possible through the input method editor system. The user, not you, is in charge of the input method that the user uses.
Rather than do that, I may as well just add buttons to perform the keypresses I hoped to invoke via a custom keyboard.
That is your only option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With