mtk硬體啟動關閉藍芽功能的項目:mtk 硬體ScanCode和keycode應用樣本,mtkscancode
項目要求:該項目由於沒有使用android5.0,導致啟動bluetooth的藍芽audio slave功能必須使用第三方模組,該第三方模組,啟動是通過android主板通過GPIO控制。UI介面是通過圖形選擇或者一個kpd組合按鍵來開啟關閉或者是啟動藍芽搜尋功能。
1,使用者按鍵的偵測:
標準的行為,使用者的組合按鍵,kernel裡面向上層發送scancode,然後framework把scancode轉換成keycode的keyevent,該keyevent會被PhoneWindows接受並處理。
對於mtk,從按鍵到keycode,已經被封裝起來,這個封裝的工具就是dct.
例如,我們的公事包按鍵是:KCOL2+KROW1,我們可以在圖形工具中如選擇我們的配置
在例子中,我們設定該案例的keycode是SYM
當然,也可以自己定義新的keycode,我嫌麻煩,就直接使用現成的,如何定義新的按鍵,請看附錄:
2,偵測使用者按鍵行為,發送相應的intent
上面的keycode在發送到各個window之前,是被PhoneWindowManager.java接收到的,在其中有一個方法:
@Override
public intinterceptKeyBeforeQueueing(KeyEvent event, int policyFlags, booleanisScreenOn) {
望文生義,看名字我們就知道這個函數的作用。我們在代碼中如下攔截:
if (keyCode== KeyEvent.KEYCODE_SYM) {
Log.e("zcfdebug","nowwe catch the bluetooth button action !");
if (down){
Log.e("zcfdebug","nowwe catch the bluetooth button down !");
}
if (up){
Log.e("zcfdebug","nowwe catch the bluetooth button up !");
}
return 1;
}
當然,KEYCODE_SYM是原來系統中已經定義的keycode,其實就是IME的選擇,我們需要屏蔽這個功能,在alps/frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java:
/**
* @hide
*/
public voiddispatchKeyEvent(Context context, int seq, KeyEvent key,
FinishedEventCallback callback) {
booleanhandled = false;
/*zcfdebug--<<
synchronized(mH) {
if(DEBUG) Log.d(TAG, "dispatchKeyEvent");
if(mCurMethod != null) {
if(key.getAction() == KeyEvent.ACTION_DOWN
&& key.getKeyCode() == KeyEvent.KEYCODE_SYM) {
showInputMethodPickerLocked();
handled = true;
}else {
try {
if (DEBUG) Log.v(TAG, "DISPATCH KEY: " + mCurMethod);
final long startTime = SystemClock.uptimeMillis();
enqueuePendingEventLocked(startTime, seq, mCurId, callback);
mCurMethod.dispatchKeyEvent(seq, key, mInputMethodCallback);
return;
} catch (RemoteException e) {
Log.w(TAG, "IME died: " + mCurId + " dropping: "+ key, e);
}
}
}
}
zcfdebug-->>*/
callback.finishedEvent(seq, handled);
}
注釋掉原有功能就好了。
按照我們的項目定義,按鍵3-5秒為藍芽狀態電源開啟搜尋功能,長按8秒以上為關閉。關閉的時候,長按8秒沒有任何動作。
if (keyCode== KeyEvent.KEYCODE_SYM) {
Log.e("zcfdebug","nowwe catch the bluetooth button action !");
if (down){
Log.e("zcfdebug","nowwe catch the bluetooth button down !");
//lastSymKeyDownTime=System.currentTimeMillis();
lastSymKeyDownTime=event.getEventTime();
}
if (up){
Log.e("zcfdebug","nowwe catch the bluetooth button up !");
SymKeyPressTime=event.getEventTime()-lastSymKeyDownTime;
//SymKeyPressTime=System.currentTimeMillis()-lastSymKeyDownTime;
Log.e("zcfdebug","theSymKeyPressTime is "+SymKeyPressTime);
if(SymKeyPressTime>2000&& SymKeyPressTime<5000){
Log.e("zcfdebug","nowwe catch the bluetooth press 3 second!");
}
if(SymKeyPressTime>7000){
Log.e("zcfdebug","nowwe catch the bluetooth press 8 second!");
}
}
return 1;
}
藍芽開關等動作,我們在外邊的apk程式中實現,我們只要發送intent實現就OK了,代碼如下:
if (keyCode== KeyEvent.KEYCODE_SYM) {
Log.e("zcfdebug","nowwe catch the bluetooth button action !");
if (down){
Log.e("zcfdebug","nowwe catch the bluetooth button down !");
//lastSymKeyDownTime=System.currentTimeMillis();
lastSymKeyDownTime=event.getEventTime();
}
if (up){
Log.e("zcfdebug","nowwe catch the bluetooth button up !");
SymKeyPressTime=event.getEventTime()-lastSymKeyDownTime;
//SymKeyPressTime=System.currentTimeMillis()-lastSymKeyDownTime;
Log.e("zcfdebug","theSymKeyPressTime is "+SymKeyPressTime);
if(SymKeyPressTime>2000&& SymKeyPressTime<5000){
Log.e("zcfdebug","nowwe catch the bluetooth press 3 second!");
Intent btStartStopIntent = new Intent(BT_STARTSTOP);
mContext.sendBroadcast(btStartStopIntent);
}
if(SymKeyPressTime>7000){
Log.e("zcfdebug","nowwe catch the bluetooth press 8 second!");
Intent btPairIntent = new Intent(BT_PAIR);
mContext.sendBroadcast(btPairIntent);
}
}
return 1;
}
應用程式如何接收處理intent,將在下一篇文章描述
附錄:Howto add a new key on android ICS\ICS2:
[Description]
How to add a new keyon android ICS/ICS2
[Solution]
1.在DCTtool keypad list檔案增加新按鍵的選項
alps\mediatek\source\dct\Keypad_YuSu.cmp中添加新鍵,如SMS快速鍵
KEY_SYM
KEY_SMS
KEY_0
2.開啟DCTtool在keypad矩陣中在相應定義的按鍵位中添加新按鍵,如SMS,然後Save
3.修改linux鍵盤碼檔案input.h
由於preloader\uboot\kernel\factory等情況分開使用,相應的檔案路徑下的input.h都應該修改
為新按鍵增加鍵碼值
kernel\include\linux\input.h
bionic\libc\kernel\common\linux\input.h
external\kernel-headers\original\linux\input.h
external\qemu\linux_keycodes.h
mediatek\plaform\mt6575\preloader\src\drivers\inc\linux\input.h
Mediatek\plaform\mt6575\uboot\inc\linux\input.h
如KEY_SMS
#define KEY_SMS 252
4.增加keypadlayout檔案鍵盤對應,linux和androidkey映射
mediatek\config\<projectname>\mt6575-kpd.kl
如:
key 252 SMS
其中252是linux鍵碼,SMS是android識別key值如果是需要喚醒系統,還需要增加WAKE
如果新按鍵是全鍵盤的一些生僻字元,修改:mediatek\config\<project name>\mt6575-kpd.kcm
5.修改Java識別keycode
framework/base/include/ui/KeyCodelabels.h
KEYCODES資料結構後面增加
{"SMS",220}
framework/base/native/include/android/KeyCodes.h
在按鍵定義項增加AKEYCODE_SMS = 220;
6.修改Java鍵盤事件
framework/base/core/java/android/view/keyevent.java
/**
*@hide
*/
public static finalint KEYCODE_SMS =220;
最後的按鍵為新增的
private static finalint LAST_KEYCODE ==KEYCODE_SMS;
以上/**/注釋的code是android非開放API或變數定義的時候,需要添加JavaDoc的識別,否則要運
行makeupdate-api才能build通過
如果是系統按鍵,修改framework/base/libs/ui/input.cpp
isSystemKey()增加caseAKEYCODE_SMS:
7.修改XML檔案描述符framework/base/core/res/res/values/attr.xml
<enumname="KEYCODE_SMS" value="220" />
8.增加測實驗證log在android
framework\base\policy\src\com\android\internal\polidy\impl\phoneWindowManager.java
在interceptKeyBeforeDispatching()增加
if(keycode==KeyEvent.KEYCODE_SMS){
log.d(TAG,"interceptKeyTi KEYCODE_SMS keyCode="+ keyCode + "down=" + down + "
repeatCount=" +repeatCount + “ keyguardOn=” + keyguardOn + “ mHomePressed=”+
9.可以抓log確認,或者增加測試APK檢測
Kernal log:
<4>[253.828234]kpd:register = fffe ffff ffff ffff ff
<4>[253.828825]kpd:(pressed) HW keycode = 0
<4>[253.829348]kpd:report Linux keycode = 252
<4>[253.829857]kpd:save new keymap state
<4>[254.030814]kpd:register = ffff ffff ffff ffff ff
<4>[254.031405]kpd:(released) HW keycode = 0
<4>[254.031936]kpd:report Linux keycode = 252
<4>[254.032445]kpd:save new keymap state
Android log:
WindowManager:interceptKeyTq keycode=220 screenIsOn=true keyguardActive=false
policyFlags =#2000000 down =false canceled = false
D WindowManager:interceptKeyTi keyCode=220 down=false repeatCount=0 keyguardOn=false
mHomePressed=falsecanceled=false
D WindowManager:interceptKeyTi KEYCODE_SMS keyCode=220 down=false repeatCount=0
keyguardOn=falsemHomePressed=false canceled=false