InputConnection-Interfaceを使って、選択されたテキストを取得-変更する


本年も残すところ僅かとなりました。
皆様良い新年を迎える準備は整いましたでしょうか?

本日は、Android2.3から追加された、InputConnection-Interfaceの「getSelectedText」と「setComposingRegion」について解説します。

ソフトキーボードからアプリケーションへのテキスト送信処理をフックした形でSampleアプリを実装しました。
ユースケースが限られたAPIかと思いますが、IME等に挑戦なさりたい際には面白いInputMethodを作れるのではないかと思います。

画像はSampleアプリのもの、文字列「TechBooster」を選択すると、「Happy New Year!」に変更されます。

詳細な実装は続きから。

ソフトキーボードを実装する必要があったため、今回はSDKのSampleに付属している「Softkeyboard」を使用しています。

まずは、SoftKeyboardをEclipseにインポートします。


<Android-SDK>/samples/android-9/Softkeyboard

にSampleのソースコードがあります。
EclipseのFileメニューの「New」から、「Android Project」を選択し、

#12/31 プロジェクトのインポート方法を再修正 (@zaki50 様ありがとうございました。)

#SDKのSampleコードは非常に簡単にインポートできます。

「Build Target」に「Android 2.3」のチェックを入れた後、

「Create project from existing sample」の項目にチェックを入れます。

すると、ListBox内を変更出来る様になるので、「SoftKeyboard」を選択します。

最後にFinish。これで、プロジェクトは追加できました。

getSelectedTextとsetComposingRegion

Android2.3において、新規に追加された2つのMethodを使用します。

getSelectedText

引数 int flag 0かInputConnection-InterfaceのGET_TEXT_WITH_STYLESを指定する。
返り値 CharSequence 選択されている文字列を返す。選択されていない場合はNULL

Sampleアプリでは本Methodを使用し、選択されている文字列が特定の物(TechBooster)であれば

「a」キーを押下時に「Happy New Year!」に変更する様にしています。

setComposingRegion

引数1 int start 選択するTextの開始位置
引数2 int end 選択するTextの終了位置
返り値 boolean True → SuccessFalse → Failed

Sampleアプリでは本Methodを使用し、変更されたTextの「Happy」部分に下線を引いています。

実装は以下の通りです。
テキストを選択後、「a」キー(HARDKEY)を押下することで、
onKeyDown-Methodの内部で「KEYCODE_A」を受信し上記プロセスを実行するようにしています。

処理を1Stepごとに追うと、
getCurrentInputConnection-Methondにて、現在のInputConnectionを取得。
InputConnection#getSelectedTextをCallし、選択中のTextを取得。
取得したTextが「TechBooster」なら、
InputConnection#deleteSurroundingTextを使用し、「TechBooster」を消去。
「Happy New Year!」をTextとして挿入。
最後に InputConnection#setComposingRegion をCallし、Happyの5文字を選択。
という流れです。

    @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            /* 省略... */
            case KeyEvent.KEYCODE_A:
            	if(DEBUG) Log.i("SOFTKEY","Key_A onDown");
            	InputConnection mInputConnection  = getCurrentInputConnection();

            	CharSequence cs = mInputConnection.getSelectedText(0);
            	if(cs.equals("TechBooster")){
            		mInputConnection.deleteSurroundingText(cs.length(), 0);
            		mInputConnection.commitText("Happy New Year!", 1);
            	}

            	boolean bb = mInputConnection.setComposingRegion(0, 5);

            	if(DEBUG) Log.i("SOFTKEY","selection data is [" + cs + "]");
            	return true;
            /* 省略... */

—Sample Code—

http://techbooster.googlecode.com/svn/trunk/SoftKeyboard_Tech