編輯:關於Android編程
(1) 使用Android Studio建立一個沒有Activity的項目,對於一個簡單的輸入法而言,MainActivity並不是必要的,只需要一個輸入法服務即可。因此,該項目mainfest.xml文件可以如下定義:
(2) mainfest.xml文件中使用到了資源文件xml/method,我們需要在res目錄下創建一個文件夾xml,在該文件夾下創建method.xml文件,該文件中包含了輸入法的subtype屬性,輸入法通過該屬性定義它所支持的輸入模式和語言,一個輸入法可以包含多個subtype屬性。
對於一個subtype:
label是該subtype的名字
imeSubtypeLocale是該subtype支持的語言類型
imeSubtypeMode是它所支持的模式,可以是keyboard或者voice,當輸入法被調起是,系統會把用戶選擇的mode值傳給輸入法。這裡,我們只有一個subtype,效果並不明顯。
(3) method.xml中的@string字符串保存在string.xml中,該文件在res/values目錄下,我們需要對其做修改:
AndroidXXIME XXIME 中文
xxime在manifest中定義service的android:label時被引用到,該字串用來顯示系統“語言和輸入法”中本輸入法的名字:
(4) 鍵盤布局
這個簡單的鍵盤中,我們只需要4個按鍵:
在res/layout/中添加文件keyboard.xml,定義鍵盤布局,內容如下:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
其中keyPreviewLayout表示鍵盤被按下時的布局資源。在res/layout中添加preview.xml如下:
(5) 按鍵信息定義在qwerty.xml文件中,該文件保存在res/xml目錄下:
Row表示一行,內部又包含Key表示一個按鍵,每個按鍵有兩個必填屬性:
· keyLabel:按鍵上顯示的文字
· codes:該按鍵代表的Unicode碼
我們定義的鍵盤布局如下圖所示:
(6) input服務創建
AndroidXXIME類擴展了InputMethodService,並實現了KeyboardView.OnKeyboardActionListener接口。該類的定義如下:
public class AndroidXXIME extends InputMethodService implements KeyboardView.OnKeyboardActionListener { private KeyboardView keyboardView; // 對應keyboard.xml中定義的KeyboardView private Keyboard keyboard; // 對應qwerty.xml中定義的Keyboard @Override public void onPress(int primaryCode) { } @Override public void onRelease(int primaryCode) { } @Override public void onText(CharSequence text) { } @Override public void swipeDown() { } @Override public void swipeLeft() { } @Override public void swipeRight() { } @Override public void swipeUp() { } @Override public View onCreateInputView() { // keyboard被創建後,將調用onCreateInputView函數 keyboardView = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard, null); // 此處使用了keyboard.xml keyboard = new Keyboard(this, R.xml.qwerty); // 此處使用了qwerty.xml keyboardView.setKeyboard(keyboard); keyboardView.setOnKeyboardActionListener(this); return keyboardView; } private void playClick(int keyCode){ // 點擊按鍵時播放聲音,在onKey函數中被調用 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_DONE: ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)); break; default: char code = (char)primaryCode; ic.commitText(String.valueOf(code), 1); } } }
以上內容部分參考了:寫一個Android輸入法01——最簡步驟
我們使用資源文件夾res/raw保存我們的輸入內容,該文件夾需要自己建立,輸入內容的格式如下:
阿壩州 阿東 阿海 阿克蘇地區 阿拉蕾 阿拉斯 阿聯 ……
數據的讀取采用InputStreamReader 和 BufferedReader,具體方法如下:
String res=""; Resources resources=this.getResources(); InputStream is=null; is=resources.openRawResource(R.raw.keywords); InputStreamReader reader = new InputStreamReader(is); BufferedReader breader = new BufferedReader(reader);
數據取到後就存入SQLite數據庫中:
private void createDb()throws IOException{ String res=""; Resources resources=this.getResources(); InputStream is=null; Integer i=1; try{ is=resources.openRawResource(R.raw.dongjiahua); InputStreamReader reader = new InputStreamReader(is); BufferedReader breader = new BufferedReader(reader); SQLiteDatabase db = openOrCreateDatabase("keywords", Context.MODE_PRIVATE,null); db.execSQL("CREATE TABLE IF NOT EXISTS keyword (id integer primary key autoincrement,word varchar(20),searched varchar(5))"); while((res = breader.readLine())!=null){ addData(db,i,res,"no"); i++; } breader.close(); reader.close(); db.close(); }catch (IOException e){ e.getStackTrace(); } }
在某些情況下,需要刪除數據表重新建立:
SQLiteDatabase db = openOrCreateDatabase("keywords", Context.MODE_PRIVATE,null); db.execSQL("DROP TABLE IF EXISTS keyword"); db.close();
直接執行sql 命令DROP即可。
private String getKeyword() { SQLiteDatabase db = openOrCreateDatabase("keywords", Context.MODE_PRIVATE,null); String select = "SELECT id,word FROM KEYWORD WHERE searched=?"; Cursor c = db.rawQuery(select,new String[]{"no"}); String res=""; Integer id=0; if(c.getCount()==0){ res="no data"; } if(c.moveToFirst()){ id = c.getInt(0); res = c.getString(1); db.delete("keyword","word=?",new String[]{res}); addData(db,id,res,"yes"); } db.close(); return res; }
每次只取符合條件的第一條記錄的相關字段,並將該調用信息寫入數據庫中,即把“searched”字段由“no”改為“yes”。
改寫onKey 方法:
public void onKey(int primaryCode, int[] keyCodes){ InputConnection ic = getCurrentInputConnection(); playClick(primaryCode); switch(primaryCode){ case Keyboard.KEYCODE_DELETE : try{ createDb(); }catch (IOException e){ e.getStackTrace(); } break; case Keyboard.KEYCODE_DONE: sendKeyChar('\n'); break; case 32: SQLiteDatabase db = openOrCreateDatabase("keywords", Context.MODE_PRIVATE,null); db.execSQL("DROP TABLE IF EXISTS keyword"); db.close(); default: ic.commitText(getKeyword(), 1); } }
當按下create database 時:通過creatDb 方法建立數據庫和數據表,並將數據從raw資源文件中讀取到數據表中;
當按下delete database 時:刪除數據庫中的指定數據表;
當按下INPUT 時:通過getKeyword 方法從數據庫中取得一個數據,提交到文本框中;
當按下DONE 時:向文本框中發送字符’\n’,即回車,微信的搜索開始執行。
前言 重新學習這一項技術,主要的原因,是因為以前沒有好好的學,那時總覺得作品能動,能完成工作就好了,而這種得過且過的想法,大大地影響了我的技術程度,也因此,
Android基礎入門教程——9.3 使用Camera拍照標簽(空格分隔): Android基礎入門教程本節引言 本節給大家帶來的是Android
移動app可以大致被分為三種,native、hybrid和web app。如果使用native app,你可以使用設備和操作系統的所有能力,同時,平台的性能負荷最小。然而
效果圖如下所示:一、shape 樣式:(在drawable新建--》new--》Drawable resource file 在父級標簽selector添加Item )&