在Android中建立一種新的IME

來源:互聯網
上載者:User

在Android中建立一種新的IME(Creating an Input Method))一.
1.建立一個新的IME需要繼承android.inputmethodservice.InputMethodService,這個類提供了一個IME
的基本實現,例子可以參考sdk中的SoftKeyboard的代碼。

2.IME跟其他application或service一樣會被打包成一個apk,在 AndroidManifest.xml,把它聲明成一個
service.[code]<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.fastinput">

    <application android:label="@string/app_label">

        <!-- Declares the input method service -->
        <service android:name="FastInputIME"
            android:label="@string/fast_input_label"
            android:permission="android.permission.BIND_INPUT_METHOD">
            <intent-filter>
                <action android:name="android.view.InputMethod" />
            </intent-filter>
            <meta-data android:name="android.view.im" android:resource="@xml/method" />
        </service>

        <!-- Optional activities. A good idea to have some user settings. -->
        <activity android:name="FastInputIMESettings" android:label="@string/fast_input_settings">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
            </intent-filter>
        </activity> 
    </application>
</manifest>[/code]3.IME的service生命週期如下
[img]https://docs.google.com/a/google.com/File?id=ad9xdxhtb4_043qn7phd_b[/img]

二.IME介面元素

IME有2個主要的介面元素,InputView與Candidates View。
InputView:是使用者輸入文字的地方,當IME被顯示的時候會調用InputMethodService.onCreateInputView()
,在這個函數裡建立和返回你想在IME視窗中顯示的Input View.
Candidates View:是用來提供輸入選擇,在函數InputMethodService.onCreateCandidatesView()中建立,預設
為空白。

三.設計不同的輸入類型
  一個程式的文字框可能有不同的輸入類型,比如字元,數字,url,email地址等,當你實現一種IME的時候你
就需要知道不同輸入方式的區別,IME不會自動根據不同的輸入類型來切換,所以你的IME需要支援所有的
輸入類型。至於輸入資料的驗證就交由應用程式去負責。

例如,Android中一個LatinIME提供的字元與數字輸入的介面:
[img]https://docs.google.com/a/google.com/File?id=ddvqp2ns_18g2nm5jhb_b[/img]

[img]https://docs.google.com/a/google.com/File?id=ddvqp2ns_17crk39fd9_b[/img]

調用InputMethodService.onStartInputView()的時候會傳遞一個 EditorInfo對象來判斷輸入類型。
例如使用(EditorInfo.inputType & EditorInfo.TYPE_CLASS_MASK)來判斷是屬於下面的哪種類型:
TYPE_CLASS_NUMBER
TYPE_CLASS_DATETIME
TYPE_CLASS_PHONE
TYPE_CLASS_TEXT

  密碼輸入:注意不要在你的介面中顯示密碼,除了提醒使用者外也不要把密碼儲存起來。

四.把輸入文本傳送給應用程式
   1.可以發送一個key event來實現[code]InputConnection ic = getCurrentInputConnection();
long eventTime = SystemClock.uptimeMillis();
ic.sendKeyEvent(new KeyEvent(eventTime, eventTime,
    KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, 0, 0,
    KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
ic.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
    KeyEvent.ACTION_UP, keyEventCode, 0, 0, 0, 0,
    KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));[/code]或者 [code]InputMethodService.sendDownUpKeyEvents(keyEventCode);[/code]建議對於一些 輸入模式使用第一種方法,因為有些按鍵可能被過濾。

   2.通過編輯輸入文本,主要使用以下方法。[code]getTextBeforeCursor()
getTextAfterCursor()
deleteSurroundingText()
commitText()[/code]比如,一個以Fell開頭的文本,你想把它替換成Hello![code]InputConnection ic = getCurrentInputConnection();
ic.deleteSurroundingText(4, 0);
ic.commitText("Hello", 1);
ic.commitText("!", 1);[/code]五.Word Flow
  如果你需要Word Flow或者輸入過程中動態預測輸入的文本,你可以參考如下代碼:[code]InputConnection ic = getCurrentInputConnection();
ic.setComposingText("Composi", 1);
...
ic.setComposingText("Composin", 1);
...
ic.commitText("Composing ", 1);[/code][img]https://docs.google.com/a/google.com/File?id=ddvqp2ns_0g2z84dg2_b[/img]

[img]https://docs.google.com/a/google.com/File?id=ddvqp2ns_1jnw696d3_b[/img]

[img]https://docs.google.com/a/google.com/File?id=ddvqp2ns_2crrwtbf7_b[/img]

六.攔截硬體按鍵訊息
儘管IME視窗沒有foucs,但是它最先收到硬體的按鍵訊息,如果需要處理這些硬體按鍵訊息,你只需要
重寫InputMethodService.onKeyDown() 與InputMethodService.onKeyUp(),如果你不想處理某個按鍵,記得調
用super.onKey* 。

七.其他注意點
   1.提供一個使用者可以直接從當前IME進行相關IME設定的方式。
   2.提供一個使用者可以切換不同IME的方式。
   3.讓IME介面儘快的彈出,資源或者耗時間長度的操作可以稍後載入。
   4.當IME視窗被隱藏的時候,大塊的記憶體配置最好儘快釋放
   5.確保IME能包含最常用的字元。

八.例子:
可以參考LatinIME的例子:
[url=http://android.git.kernel.org/?p=platform/packages/inputmethods/LatinIME.git;a=tree]http://android.git.kernel.org/?p=platform/packages/inputmethods/LatinIME.git;a=tree[/url]
或者1.5 SDK也提供了一個SoftKeyboard的例子。

Terry 發表於 2009-4-25 03:21

這是1.5版核心的輸入嗎?挺不錯的

fly_fire 發表於 2009-4-25 09:37

[quote]這是1.5版核心的輸入嗎?挺不錯的
[size=2][color=#999999]Terry 發表於 2009-4-25 03:21[/color] [url=http://yddev.com/bbs/redirect.php?goto=findpost&pid=96&ptid=63][img]http://yddev.com/bbs/images/common/back.gif[/img][/url][/size][/quote]

對,這是基於1.5的IME架構建立新的IME。。

yantao821015 發表於 2009-7-22 16:54

如何通過API去設定當前IME呢?
我看了下setting的代碼,他是用
Settings.Secure.putString(getContentResolver(),
            Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
但是,在SDK文檔中明確指出,該設定只能讀,不能寫。鬱悶了。。。
高人給指點一下

http://www.yddev.com/bbs/viewthread.php?tid=63

softkeyboard

總結:

SoftKeyboard.java

主要變數:

StringBuilder mComposing 用於存放向連結應用提交的字串

主要介面函數:

public void onKey(int primaryCode, int[] keyCodes) {
        if (isWordSeparator(primaryCode)) { //判斷是否為指定符號(空格,分號,冒號等)。指定符號在string.xml中
            // Handle separator 
            if (mComposing.length() > 0) { //輸入該符號之前是否有輸入
                commitTyped(getCurrentInputConnection());//將之前打的文本提交給連線應用程式,並清除輸入狀態
            }
            sendKey(primaryCode);//執行該按鍵的自身操作(輸入空格、冒號等)
            updateShiftKeyState(getCurrentInputEditorInfo());
        } else if (primaryCode == Keyboard.KEYCODE_DELETE) {
            handleBackspace();
        } else if (primaryCode == Keyboard.KEYCODE_SHIFT) {
            handleShift();
        } else if (primaryCode == Keyboard.KEYCODE_CANCEL) {
            handleClose();//關閉軟鍵盤
            return;
        } else if (primaryCode == LatinKeyboardView.KEYCODE_OPTIONS) {
            // Show a menu or somethin'
        } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE
                && mInputView != null) {//切換輸入髮狀態
            Keyboard current = mInputView.getKeyboard();
            if (current == mSymbolsKeyboard || current == mSymbolsShiftedKeyboard) {
                current = mPinyinKeyboard;//mQwertyKeyboard;
            } else if(current == mPinyinKeyboard){
    current = mQwertyKeyboard;//
   } else {
                current = mSymbolsKeyboard;
            }
            mInputView.setKeyboard(current);
            if (current == mSymbolsKeyboard) {
                current.setShifted(false);
            }
        } else {
            handleCharacter(primaryCode, keyCodes);//輸入一般字元或符號
        }
    }

    private void handleCharacter(int primaryCode, int[] keyCodes) {
        if (isInputViewShown()) {//軟鍵盤是否開啟
            if (mInputView.isShifted()) {//檢查鍵盤狀態
                primaryCode = Character.toUpperCase(primaryCode);//轉換大小寫
            }
        }
        if (isAlphabet(primaryCode) && mPredictionOn) {//用charactor.isletter()判斷是否為字元,並且之前有輸入
            mComposing.append((char) primaryCode);//向結尾處追加字元
            getCurrentInputConnection().setComposingText(mComposing, mComposing.length());//設定當前輸入文本顯示
            updateShiftKeyState(getCurrentInputEditorInfo());
            updateCandidates();
        } else {
            getCurrentInputConnection().commitText(
                    String.valueOf((char) primaryCode), 1);//直接將當前輸入的字元提交給連結的應用
        }
    }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.