專利名稱:Linux應(yīng)用在Android手機(jī)上運(yùn)行時(shí)整合中文輸入法的方法
技術(shù)領(lǐng)域:
本發(fā)明涉及Android手機(jī)領(lǐng)域,尤其是一種Linux應(yīng)用在Android手機(jī)上運(yùn)行時(shí) 整合中文輸入法的方法。
背景技術(shù):
以手機(jī)為代表的智能化移動終端設(shè)備既是計(jì)算機(jī)技術(shù)的一個(gè)重要發(fā)展方向,又是 一個(gè)競爭十分激烈的市場。自從谷歌公司和開放手機(jī)聯(lián)盟推出Android操作系統(tǒng)和基于 Android的手機(jī)以來,很快就在世界手機(jī)市場上占有了不小的份額,各種Android手機(jī)層出 不窮,由中國移動開發(fā)并推出的OPhone也是基于Android的,也是一種Android手機(jī)。所謂Android操作系統(tǒng),實(shí)際上是對Linux操作系統(tǒng)的一種改編和擴(kuò)充,它的內(nèi)核 基本上就是Linux的內(nèi)核,但是在用戶空間卻專門針對手機(jī)和移動終端設(shè)備的特點(diǎn)作了大 幅的改進(jìn)和增強(qiáng),這些改動大都與編程模式和圖形界面、即圖形化用戶界面(GUI)有關(guān)。在帶圖形界面的Linux操作系統(tǒng)中,有關(guān)圖形界面的功能都是由X視窗系統(tǒng)提供 的,輸入法也是圖形界面功能的一部分。運(yùn)行著應(yīng)用軟件的進(jìn)程都不直接讀取鍵盤輸入,而 只是通過進(jìn)程間通信從X服務(wù)進(jìn)程獲取輸入。人機(jī)交互的輸入先由本系統(tǒng)中唯一的X服務(wù) 進(jìn)程讀取,由X服務(wù)進(jìn)程統(tǒng)一加以前期的處理,然后根據(jù)屏幕上光標(biāo)的當(dāng)前位置以及當(dāng)前 處于“聚焦”狀態(tài)的視窗配送給合適的進(jìn)程/線程。這里所說的前期處理可簡可繁,簡單的 處理由X視窗本身加以實(shí)施,復(fù)雜的處理則要由外掛的程序模塊加以處理,而輸入法就是 這樣的外掛程序模塊。所以,用于Linux應(yīng)用的輸入法實(shí)際上是為X視窗而開發(fā)的輸入法。X視窗屬于另一個(gè)開源軟件項(xiàng)目,早在Unix時(shí)代即已存在。由于Linux系統(tǒng)大多 離不開圖形界面,X視窗實(shí)際上已經(jīng)成了 Linux操作系統(tǒng)的一部分。為適應(yīng)手機(jī)和其它嵌入 式系統(tǒng)的需要,人們還將X視窗加以裁剪、縮編、簡化,成為一個(gè)小型化的版本稱為TinyX, 所以TinyX是專門與嵌入式Linux配對使用的X視窗系統(tǒng)。正因?yàn)槿绱?,我們把為手機(jī)上 的Linux應(yīng)用而開發(fā)的輸入法稱為TinyX輸入法??墒?,在包括Android手機(jī)在內(nèi)的Android系統(tǒng)中,卻甩開了 X視窗,包括輸入法 在內(nèi)的所有圖形界面功能全都由Android自己提供。事實(shí)上,人們已經(jīng)為Android開發(fā)了 不少各式各樣的輸入法。同樣,Android也有自己類似于TinyX那樣的集中處理和配送輸 入信息的機(jī)制。然而,如果我們要在Android手機(jī)上運(yùn)行普通的Linux應(yīng)用,輸入法就成為一個(gè)問 題。這是因?yàn)椋琇inux應(yīng)用是必須與TinyX配套運(yùn)行的,而用了 TinyX,就只能使用與其配套 的TinyX輸入法,可是所有的Android應(yīng)用卻只能繼續(xù)使用由Android提供的輸入法。這 樣,就會形成TinyX和Android同時(shí)共存的局面,此時(shí)來自鍵盤和其它輸入設(shè)備(例如觸摸 式屏幕)的物理狀態(tài)信息不再由唯一的實(shí)體加以統(tǒng)一處理和配送。這會造成兩方面的問 題。首先,由于“政出多門”,就可能會有兩邊爭搶輸入信息的情況發(fā)生。再說,即使不發(fā)生 爭搶輸入信息的情況,使用者也可能只好在與Android應(yīng)用交互時(shí)采用一種輸入法;而在與Linux應(yīng)用交互時(shí)采用另一種輸入法,這顯然會給使用者帶來不便。所以,要在Android手機(jī)上運(yùn)行別的Linux應(yīng)用,就需要解決整合輸入法的問題, 使Linux應(yīng)用能采用Android的輸入法。而本發(fā)明的內(nèi)容和特點(diǎn)就是為這個(gè)問題的解決提供一種方法,將Linux應(yīng)用跟 Android的輸入法整合在一起,讓Android成為統(tǒng)一接收、處理、配送人機(jī)交互輸入信息的 唯一實(shí)體,向在Android手機(jī)上運(yùn)行的Linux應(yīng)用提供人機(jī)交互輸入信息,讓使用者不需要 在同一臺手機(jī)上因?yàn)橐c不同的應(yīng)用交互而不得不使用不同的輸入法。
發(fā)明內(nèi)容
為解決輸入法整合的問題,本發(fā)明提供了一種將Linux應(yīng)用與Android的輸入法 相整合的方法,使普通的Linux應(yīng)用在Android手機(jī)上運(yùn)行時(shí)能統(tǒng)一使用由Android提供 的中文輸入法。Android應(yīng)用都是用Java語言編寫的,Android為應(yīng)用程序提供了一些Java語言 的“類(Class)”,而每個(gè)類中又有若干“方法(Method)”,大體上相當(dāng)于C語言編程時(shí)要用 到的各種庫函數(shù)??墒?,在面向?qū)ο蟮腏ava語言中,應(yīng)用程序可以很方便地替換或擴(kuò)充這 些“方法”。例如,onTouchEventO和onKeyDownO是Android提供的兩個(gè)方法、即函數(shù);每 當(dāng)使用者在觸摸屏上有所動作時(shí),當(dāng)前應(yīng)用進(jìn)程的onTouchEventO就會受到系統(tǒng)的調(diào)用; 而每當(dāng)使用者按下一個(gè)按鍵時(shí),則當(dāng)前應(yīng)用進(jìn)程的onKeyDownO就會受到系統(tǒng)的調(diào)用。這 樣的函數(shù)也稱為“回調(diào)函數(shù)”。Android應(yīng)用的開發(fā)者可以選用默認(rèn)的、由Android提供的 回調(diào)函數(shù),也可以將其中的若干回調(diào)函數(shù)替換成自己寫的同名(并有相同調(diào)用參數(shù)的)函 數(shù),起到“攔截”的作用。本發(fā)明采用的方法是在Android這一邊為Linux應(yīng)用創(chuàng)建一個(gè)代理進(jìn)程,由這個(gè) 代理進(jìn)程在Android這一邊運(yùn)行,其作用是攔截人機(jī)交互輸入、并將其轉(zhuǎn)發(fā)給TinyX,最后 到達(dá)運(yùn)行著Linux應(yīng)用的進(jìn)程。(1)、每當(dāng)啟動一個(gè)Linux應(yīng)用時(shí),就在Android系統(tǒng)中為其創(chuàng)建一個(gè)代理進(jìn)程 AppProxy,這個(gè)進(jìn)程與實(shí)際的應(yīng)用進(jìn)程“同生共死”,有著相同的生存期。(2)、由應(yīng)用代理進(jìn)程AppProxy創(chuàng)建一個(gè)人機(jī)交互輸入攔截線程。這個(gè)線程攔截 來自Android的人機(jī)交互輸入,并將其轉(zhuǎn)發(fā)給TinyX。(3)、修改TinyX的代碼,斷開其原有與人機(jī)交互輸入設(shè)備的連接,改成通過 socket與代理進(jìn)程建立連接,并從socket接收來自代理進(jìn)程的人機(jī)交互輸入信息。、修改TinyX的代碼,使其將來自代理進(jìn)程的中文信息轉(zhuǎn)發(fā)、配送給應(yīng)用進(jìn)程。這樣,人機(jī)交互輸入就會統(tǒng)一流經(jīng)由Android提供的輸入法和配送機(jī)制,先由代 理進(jìn)程加以接收,再轉(zhuǎn)發(fā)給TinyX服務(wù)進(jìn)程,最后到達(dá)運(yùn)行著Linux應(yīng)用的進(jìn)程。在這整個(gè) 過程中只有一套輸入信息的處理和配送機(jī)制,只使用一種輸入法,這就解決了輸入法整合 的問題。由于TinyX是X視窗的一個(gè)子集,其源代碼就是X視窗的源代碼的一部分,本發(fā)明 所述方法同樣也適用于X視窗。本發(fā)明有益的效果是本發(fā)明提供了一種輸入代理機(jī)制,在Android系統(tǒng)中為運(yùn) 行于Android以外的Linux應(yīng)用提供一個(gè)作為Android應(yīng)用的代理進(jìn)程,使人機(jī)交互時(shí)的輸入統(tǒng)一流經(jīng)由Android提供的輸入法和配送機(jī)制,先由代理進(jìn)程加以接收,再轉(zhuǎn)發(fā)給 TinyX服務(wù)進(jìn)程,最后到達(dá)運(yùn)行著Linux應(yīng)用的進(jìn)程,其效果是實(shí)現(xiàn)了 TinyX和Android關(guān) 于中文輸入法的整合。
附圖1是將TinyX的輸入法與Android整合之前的系統(tǒng)示意圖; 附圖2是按本發(fā)明所述方法將TinyX整合到Android、統(tǒng)一使用其輸入法之后的系
統(tǒng)示意圖;附圖3是AppProxy的程序流程圖。
具體實(shí)施例方式下面結(jié)合附圖和實(shí)施例對本發(fā)明作進(jìn)一步說明附圖1中的豎直虛線將系統(tǒng)分成兩半,右邊是Android系統(tǒng)及其應(yīng)用,左邊是 Linux本身的應(yīng)用,二者共用同一個(gè)Linux內(nèi)核。圖中有兩個(gè)Android進(jìn)程,它們的人機(jī)交互輸入都來自Android、包括其輸入法。 輸入法的輸入信息來自外部設(shè)備、包括觸摸屏和按鍵、及其設(shè)備驅(qū)動程序。輸入法的輸出, 則由Android則根據(jù)當(dāng)前各進(jìn)程的活動情況配送給合適的進(jìn)程作為其輸入。輸入法對于 Android應(yīng)用是透明的,Android應(yīng)用感覺不到輸入法的存在,只是從Android接收經(jīng)過處 理加工的人機(jī)交互輸入。而Linux這一邊,則與Android無關(guān),Linux應(yīng)用進(jìn)程從TinyX接收人機(jī)交互輸入, 而TinyX則直接從操作系統(tǒng)內(nèi)核獲取輸入信息,如果使用者不采用英語就得由TinyX提供 自己的輸入法。這樣就給使用者帶來不便。更麻煩的是,在缺乏統(tǒng)一的仲裁和協(xié)調(diào)機(jī)制的條件下, 兩個(gè)互相獨(dú)立的輸入法都從相同的外部設(shè)備及其驅(qū)動獲取輸入,就會發(fā)生兩邊爭搶輸入的 情況發(fā)生。附圖2中在Android這一邊多了一個(gè)代理進(jìn)程AppProxy,這個(gè)進(jìn)程在Android這 一邊代表著Linux應(yīng)用進(jìn)程,其視窗位置和大小被設(shè)置成與其所代表的應(yīng)用進(jìn)程一樣。輸 入法則只有一個(gè),那就是Android的輸入法,其輸出由Android遞交給代理進(jìn)程,再由代理 進(jìn)程轉(zhuǎn)發(fā)給TinyX。至于TinyX,則不再直接從操作系統(tǒng)內(nèi)核獲取人機(jī)交互輸入,而改成從Android這 一邊得代理進(jìn)程接收盛載著人機(jī)交互輸入信息的“消息”,再把這消息轉(zhuǎn)發(fā)給Linux這一邊 的應(yīng)用進(jìn)程。附圖3是AppProxy的程序流程。當(dāng)用戶要啟動一個(gè)Linux應(yīng)用時(shí),實(shí)際啟動的是 AppProxy,原本用來啟動Linux應(yīng)用所需的命令行則作為(對于AppProxy的)命令行參數(shù) 傳給AppProxy。啟動之后,AppProxy首先創(chuàng)建一個(gè)連接管理線程,由這個(gè)線程根據(jù)命令行 參數(shù)啟動Linux應(yīng)用,然后就等待Linux應(yīng)用的運(yùn)行結(jié)束。而主線程則負(fù)責(zé)攔截、接收人機(jī) 交互輸入并將其轉(zhuǎn)發(fā)給TinyX。一旦Linux應(yīng)用結(jié)束運(yùn)行,整個(gè)AppProxy進(jìn)程便立即退出 運(yùn)行。這樣,AppProxy與具體的Linux應(yīng)用便有(基本)相同的生存期,成為同生共死的 關(guān)系。
本方法的具體實(shí)施涉及對TinyX即X的源代碼的修改,X是開源軟件,其源代碼 XFree86可從有關(guān)網(wǎng)站獲取。下面分五個(gè)方面說明本方法的一個(gè)實(shí)施例。注意同一個(gè)方法 可以有多種不同的實(shí)施,這里所提供的只是其中之一。1、作為應(yīng)用代理的可執(zhí)行程序AppProxy為把Linux應(yīng)用的人機(jī)交互輸入整合到Android,需要在Android這一邊為Linux 應(yīng)用創(chuàng)建一個(gè)代理進(jìn)程,由這個(gè)代理進(jìn)程在Android這一邊攔截人機(jī)交互輸入、并將其轉(zhuǎn) 發(fā)給TinyX,最后到達(dá)運(yùn)行著Linux應(yīng)用的進(jìn)程。在Android系統(tǒng)中,一個(gè)應(yīng)用進(jìn)程稱為一個(gè)Activity,是一個(gè)Java語言中的“類 (Class) ”,將這種類擴(kuò)展成一個(gè)自定義的類,就是一個(gè)Android應(yīng)用,最后在Android的顯 示屏上就會有一個(gè)圖標(biāo),點(diǎn)擊這個(gè)圖標(biāo)就會執(zhí)行這個(gè)類中的“方法(Method),,onCreate ()。 所以,onCreateO就相當(dāng)于C程序中的main()。下面給出有關(guān)的偽代碼
public class RunAppActivity extends Activity {
......//這個(gè)自定義類中擴(kuò)充出來的其它方法
private JniMethod mJniMethod = new JniMethod(); //需要用到 JNI
Called when the activity is first created. */ @0verride
public void onCreate(Bundle savedlnstanceState) { //相當(dāng)于C程序中的main() super.onCreate(savedlnstanceState);
JniMethod.startApp(StartAppName.getBytes()); //啟動執(zhí)行 Linux 那一邊的 App
// set layout
layout = (AbsoluteLayout) findViewById(R. id.layout);
if(layout!=null){ Il create View
appView = new AppView(Ihis); //有個(gè)View才能接收來自輸入法的字符串
// add surface view for drawing layout.addView(appView, O, layoutparams);
} //end onCreate
......//這個(gè)自定義類中擴(kuò)充出來的更多方法
}這個(gè)Activity最主要的任務(wù)就是啟動Linux那一邊的應(yīng)用,具體方法是通過Java 語言的JNI機(jī)制調(diào)用其方法startApp,而JNI機(jī)制會自動將其轉(zhuǎn)化成對C語言函數(shù)Java_ Android_AppProxy_jni_JniMethod_startApp ()的調(diào)用JNIEXPORT jint JNICALL
Java_Android_AppProxyJni_JniMethod_startApp( JNIEnv *env,
jclass clazz, j byte Array appName)
{
先將有關(guān)環(huán)境變量與appName整合出一個(gè)Linux App的全路徑名name; pid_tpid = fork(); //創(chuàng)建子進(jìn)程
if(pid = 0) {
//這是被創(chuàng)建的子進(jìn)程,這個(gè)進(jìn)程將運(yùn)行Liimx App。
if(execl(7bin/sh", ”/bin/sh", name, NULL) < 0) {
return-1; //啟動 App 失敗
return 1; //這是當(dāng)前進(jìn)程本身
}這段程序通過Linux的系統(tǒng)調(diào)用fork()創(chuàng)建一個(gè)子進(jìn)程,然后讓這子進(jìn)程執(zhí)行 Linux那一邊的具體應(yīng)用程序。這樣就保證了代理進(jìn)程與應(yīng)用進(jìn)程的“同生”;但是這還不 夠,還得保證二者的“公死”,為此可由應(yīng)用進(jìn)程在退出運(yùn)行前夕向代理進(jìn)程發(fā)送一個(gè)通知, 讓代理進(jìn)程也及時(shí)退出運(yùn)行,具體的實(shí)現(xiàn)見下面的第三條。此外,在Activity的onCreateO中還需要創(chuàng)建一個(gè)View,就是上面代碼中的 AppView,用來作為人機(jī)交互輸入的接收緩沖。代理進(jìn)程的View實(shí)際上從來都不顯示,但是邏輯上還是要設(shè)置一個(gè)屏幕位置和 范圍,并且這個(gè)位置和范圍必須跟具體應(yīng)用進(jìn)程所占的位置和范圍相同。這是因?yàn)锳ndroid 根據(jù)點(diǎn)擊位置尋找屬于哪一個(gè)進(jìn)程,這樣才能使Android將人機(jī)交互輸入遞交給代理進(jìn)程。有關(guān)的這些程序設(shè)計(jì)對于Android應(yīng)用的開發(fā)者而言應(yīng)該沒有什么困難,如有困 難可參閱“深入淺出Google Android","Pro Android”等參考書。2、修改TinyX的源代碼,切斷與鍵盤和鼠標(biāo)器或觸摸屏的聯(lián)系TinyX原來直接從鍵盤和鼠標(biāo)器及觸摸屏直接讀入信息,現(xiàn)在要讓它改從應(yīng)用代 理讀取、并且僅從應(yīng)用代理讀取人機(jī)交互輸入信息,所以需要切斷TinyX與鍵盤和鼠標(biāo)器 或觸摸屏的聯(lián)系。為達(dá)到這個(gè)目的,只需要在TinyX源代碼的XserveiAdixViain. c中找 到其主函數(shù)mainO,把里面對于hithput ()的調(diào)用注釋掉,使TinyX在初始化時(shí)跳過 IritInputO就行了,因?yàn)殒I盤、鼠標(biāo)器、觸摸屏的初始化都是在這個(gè)函數(shù)中完成的。3、定義 一個(gè)雙方通信的協(xié)議,并在AppProxy與TinyX之間建立Socket連接將TinyX的人機(jī)交互輸入功能整合到Android之后,TinyX就人機(jī)交互輸入而言 只起著中介的作用,其輸入來自Android這一邊的代理進(jìn)程。為此需要在TinyX與代理進(jìn) 程之間定義一個(gè)雙方通信的協(xié)議、主要是消息類型,在我們這個(gè)實(shí)施例中定義如下public class ProxyConnectionText extends EditText {
public static final String TAG = "LinuxApp";
public static final int TINYX_KEY_EVNENT = 0; public static final int TINYX_MOUSE一EVENT = 1; public static final int TINYX_STRING_EVENT = 3; public static final int TINYX_EXIT_EVENT = 10;
public static final int TINYX_KEY_DOWN = 4;
public static final int TINYX_KEY_UP = 5;
public static final int TINYX_MOUSE_DOWN = 8;
public static final int TINYX_MOUSE_UP = 9;
public static final int TINYX_MOUSE_LONG_PRESS = 11;
public static final int TINYX_ENTER_SCANKEY = 28; public static final int TINYX_DEL_SCANKEY = 14; public static final int TINYX_SPACE_SCANKEY = 57;
public static final int PROXY_HIDE_S OFT—INPUT 二 0; public static final int PROXY_SHOW_SOFT_INPUT = 1; public static final int PROXY_APP_EXIT = 2; public static final int PROXY_MUSIC_START_EVENT = 20;
}這里所定義的消息類型,有些是從代理進(jìn)程發(fā)往TinyX、再到應(yīng)用進(jìn)程的,例如 TINYX_KEY_EVNENT、TINYX_STRING_EVENT、TINYX_KEY_D0WN 等等;有的則是反方向的,例如 PR0XY_HIDE_S0FT_INPUT、PR0XY_APP_EXIT 等。在實(shí)際運(yùn)行中,TinyX作為一個(gè)系統(tǒng)服務(wù)進(jìn)程是一直在運(yùn)行的,這個(gè)服務(wù)進(jìn)程創(chuàng)建 了一組socket供客戶進(jìn)程前來連接;而代理進(jìn)程及其所代理的Linux應(yīng)用進(jìn)程則在需要時(shí) 才啟動。啟動之后,代理進(jìn)程和應(yīng)用進(jìn)程都通過自己的socket連接到由TinyX建立的某個(gè) socket,從而建立起與服務(wù)進(jìn)程的連接。其中應(yīng)用進(jìn)程與TinyX的連接是原來就有的,代理 進(jìn)程與TinyX的連接則是新增的。代理進(jìn)程不僅僅通過這個(gè)連接向TinyX發(fā)送人機(jī)交互輸 入信息,也從TinyX接收來自應(yīng)用進(jìn)程的命令和通知并加以執(zhí)行。例如,應(yīng)用進(jìn)程在某些條 件下可能會命令代理進(jìn)程在顯示屏上彈出軟鍵盤或收起軟鍵盤。特別地,當(dāng)應(yīng)用進(jìn)程要退 出運(yùn)行時(shí),還會(經(jīng)由TinyX)向代理進(jìn)程發(fā)出一個(gè)通知,讓代理進(jìn)程也及時(shí)退出運(yùn)行,這樣 才能使二者“同生共死”。為此,代理進(jìn)程可以專門創(chuàng)建一個(gè)線程,來管理與TinyX的socket 連接并負(fù)責(zé)執(zhí)行來自TinyX、實(shí)際上是來自應(yīng)用進(jìn)程的命令。在本實(shí)施例中,這是由下面的 代碼實(shí)現(xiàn)的public class ProxyConnectionText extends EditText
{
...... Il ProxyConnectionEdit 中的其它方法
public class messageHandleThread extends Thread //應(yīng)用代理中的一個(gè)線程 {
@0verride
public void run() {
//connection,連接到由TinyX創(chuàng)建用于代理進(jìn)程的socket。 fd = socket.serv_connect("/tmp/.TinyX/AppProxy");
while(true && fd >0) {
Log.i(TAG,"messageHandleThread start"); fds
= (byte)fd; fds[l] = (byte)255;
se_ret = socket. serv_se 丨 ect(fds); //等待來自 TinyX 的消息
//determine the message type,有消息到來,從socket讀取消息。 se_ret = socket.serv_read(fd,recive_buf,PROXY_TYPE_SIZE);
//根據(jù)消息的類型執(zhí)行特定的操作 switch (recive_type) {
case PROXY—SHOW—SOFT—INPUT: //彈出軟鍵盤break;
case PROXY_HIDE_SOFT_INPUT: //隱藏軟鍵盤
break;
case PROXY一APP一EXIT: //APP己退出運(yùn)行
obj.finish(); //使整個(gè)應(yīng)用代理退出運(yùn)行 break;
default:
break; } “ end switch
}
} //end messageHandleThread ...... // ProxyConnectionEdit 中的其它方法
}4、在AppProxy中攔截人機(jī)交互輸入并轉(zhuǎn)發(fā)給TinyX與TinyX建立起socket連接之后,代理進(jìn)程便可攔截來自鍵盤、觸摸屏、和輸入法 的人機(jī)交互輸入,并將其轉(zhuǎn)發(fā)給TinyX。在Android的程序設(shè)計(jì)框架中,每個(gè)Activity都可以通過onKeyDown ()、 onKeyUp ()、onTouchEvent ()、onTextChanged()等“方法”、即函數(shù)獲取人機(jī)交互輸入。這些 函數(shù)稱為“回調(diào)函數(shù)”,每當(dāng)使用者對輸入設(shè)備有所操作時(shí),相應(yīng)的回調(diào)函數(shù)就會得到調(diào)用。 以onTextChangedO為例,使用者要輸入一個(gè)漢字時(shí),實(shí)際上需要輸入多個(gè)英文字符,這時(shí) 候就要啟用輸入法。對于具體的輸入法,使用者輸入多個(gè)英文字符屬于中間過程,叫做“合 成(Composition) ”,有個(gè)用來合成的緩沖區(qū),在此過程中緩沖區(qū)的內(nèi)容逐步在變化,這個(gè)過 程一直要到使用者確認(rèn)完成了一個(gè)漢字或詞組的合成時(shí)才會結(jié)束。每當(dāng)這緩沖區(qū)的內(nèi)容發(fā) 生變化時(shí),應(yīng)用進(jìn)程的onTextChanged ()就會受到Android的調(diào)用,所合成的漢字或詞組則 作為字符串存放在一個(gè)緩沖區(qū)中。
public void onTextChanged(CharSequence text,int start,int before,int after) {
if(is_compossing_start() >= 0) //還在合成的過程中 {
input—is一 start = 1 ; return;
}if(input_is_start == 1 && is_compossing_start() == -1) { //原朵己在合成的過程 ,但現(xiàn)在運(yùn)個(gè)過程已經(jīng)結(jié)束,合成已完成。 sendStringToTinyO; //將合成好的字符串發(fā)送給TinyX -
input一is_start - 0; return;
}
sendStringToTinyx(); //未啟用輸入法,把緩沖區(qū)的內(nèi)容直接發(fā)送給TinyX。
}5、由TinyX將來自AppProxy的人機(jī)交互輸入轉(zhuǎn)發(fā)配送給Linux應(yīng)用TinyX是個(gè)服務(wù)進(jìn)程,其主循環(huán)是Dispatch (),這個(gè)函數(shù)的代碼在XserVer\diX\ dispatch, c中。在這個(gè)主循環(huán)中,TinyX的主線程在一個(gè)函數(shù)WaitForSomething()中通過 系統(tǒng)調(diào)用select ()監(jiān)視來自外部設(shè)備和Socket的輸入,這段代碼在源文件feerVer\0S\ WaitFor. c 中
int WaitForSomething(int *pClientsReady)
while (1) {
/* handle the work Q */ if (workQueue)
Process WorkQueueQ;
XFD_COPYSET(&AllSockets, &LastSelectMask);
BIockHandIer(&wt, (pointer) &LastSelectMask); if (NewOutputPending) FlushAllOutputO;
if (AnyClientsWriteBlocked) {
XFD_COPYSET(&ClientsWriteBlocked, &clientsWriteable); i = Select(MAXSOCKS, &LastSelectMask, &clientsWriteable, NULL, wt); } else {
i = Select(MAXSOCKS, &LastSelectMask, NULL, NULL, wt);
}
selecterr = errno;
WakeupHandler(i,(unsigned long *) &LastSelectMask);
}
return nready;
}
每當(dāng)TinyX的這個(gè)線程從系統(tǒng)調(diào)用select ()返回時(shí),必定是某個(gè)socket或I/O 端口上發(fā)生了什么事,返回值i指明具體的socket或端口,下面就由WakeupHandler()加 以處理并作出反應(yīng)。對于socket,此時(shí)要判別這是通往代理進(jìn)程的socket還是通往應(yīng)用進(jìn) 程的socke,如果是通往代理進(jìn)程的socket,那就由函數(shù)SerV_proXy()加以處理
int serv_proxy(ClientPtr client)
{
ret = read(fd,wpReq.request—buf, wpReq.buflen); //從socket讀入來自代理進(jìn)程的消息
switch (wpReq.type) {
case PROXY_STR: //如果是合成好的漢字或詞組
handIe_proxy_striiig(&wpReq); //將消息轉(zhuǎn)發(fā)給應(yīng)用進(jìn)程 break;
default: break; }/* end switch */
return 0;
}以來自代理進(jìn)程的漢字或詞組為例,這里通過handle_pr0Xy_String()將其轉(zhuǎn)發(fā)
給應(yīng)用進(jìn)程
handle_proxy_string(WineProxyRequestPtr wpReqPtr) { 一
xEvent xE; /* get string */
memcpy(&proxy_str[StrWriteNum-H-]
, wpReqPtr->request一buf,wpReqPtr->buflen);
xE.u.u.detail = 0; xE.u.u.type = KeyPress;
mieqEnqueue(&xE); //轉(zhuǎn)發(fā),這個(gè)函數(shù)是由TinyX提供的。
}要將一個(gè)字符串轉(zhuǎn)發(fā)給應(yīng)用進(jìn)程時(shí),需要準(zhǔn)備好一個(gè)xEvent數(shù)據(jù)結(jié)構(gòu),然后調(diào)用 由TinyX提供的庫函數(shù)mieqEnqueue (),這樣就可以了。通過上述五個(gè)方面的程序設(shè)計(jì)和對于TinyX代碼的修改,就可以實(shí)現(xiàn)本發(fā)明所述將Linux應(yīng)用與Android的輸入法相整合的方法,使普通的Linux應(yīng)用在Android手機(jī)上 運(yùn)行時(shí)能統(tǒng)一使用由Android提供的中文輸入法。
值得注意的是,雖然本發(fā)明主要的目的在于中文輸入法的整合,但實(shí)際上也附帶 實(shí)現(xiàn)了普通英文輸入的整合。除上述實(shí)施例外 ,本發(fā)明還可以有其他實(shí)施方式。凡采用等同替換或等效變換形 成的技術(shù)方案,均落在本發(fā)明要求的保護(hù)范圍。
權(quán)利要求
1. 一種Linux應(yīng)用在Android手機(jī)上運(yùn)行時(shí)整合中文輸入法的方法,其特征在于 1. 1)每當(dāng)啟動一個(gè)Linux應(yīng)用時(shí),就在Android系統(tǒng)中為其創(chuàng)建一個(gè)代理進(jìn)程 AppProxy,這個(gè)代理進(jìn)程與實(shí)際的應(yīng)用進(jìn)程有著相同的生存期;1. 2)由應(yīng)用代理進(jìn)程AppProxy攔截來自Android的人機(jī)交互輸入,并將其轉(zhuǎn)發(fā)給 TinyX ;1. 3)修改TinyX的代碼,斷開其原有與人機(jī)交互輸入設(shè)備的連接,改成通過socket與 代理進(jìn)程建立連接,并從socket接收來自代理進(jìn)程的人機(jī)交互輸入信息;1. 4)修改TinyX的代碼,使其將來自代理進(jìn)程的中文信息轉(zhuǎn)發(fā)給應(yīng)用進(jìn)程。
全文摘要
本發(fā)明涉及一種Linux應(yīng)用在Android手機(jī)上運(yùn)行時(shí)整合中文輸入法的方法,1.1)每當(dāng)啟動一個(gè)Linux應(yīng)用時(shí),就在Android系統(tǒng)中為其創(chuàng)建一個(gè)代理進(jìn)程AppProxy,這個(gè)代理進(jìn)程與實(shí)際的應(yīng)用進(jìn)程有著相同的生存期;1.2)由應(yīng)用代理進(jìn)程AppProxy攔截來自Android的人機(jī)交互輸入,并將其轉(zhuǎn)發(fā)給TinyX;1.3)修改TinyX的代碼,斷開其原有與人機(jī)交互輸入設(shè)備的連接,改成通過socket與代理進(jìn)程建立連接,并從socket接收來自代理進(jìn)程的人機(jī)交互輸入信息;1.4)修改TinyX的代碼,使其將來自代理進(jìn)程的中文信息轉(zhuǎn)發(fā)給應(yīng)用進(jìn)程。本發(fā)明有益的效果是本發(fā)明提供了一種輸入代理機(jī)制,在Android系統(tǒng)中為運(yùn)行于Android以外的Linux應(yīng)用提供一個(gè)作為Android應(yīng)用的代理進(jìn)程,實(shí)現(xiàn)了TinyX和Android關(guān)于中文輸入法的整合。
文檔編號H04M1/725GK102073542SQ20101061954
公開日2011年5月25日 申請日期2010年12月22日 優(yōu)先權(quán)日2010年12月22日
發(fā)明者徐鼎鼎, 毛德操, 王承志 申請人:浙大網(wǎng)新科技股份有限公司