android 隐藏鼠标光标,Android7.1下显示/隐藏鼠标
本帖最后由 lxp 于 2017-8-9 16:16 編輯
功能:長按遙控的search鍵后,切換為飛鼠模式。
問題:
1.切換飛鼠模式鼠標沒有顯示出來(要按其他上下左右按鈕才開始顯示)
2.切換回按鍵模式后,鼠標是自動等待一段時間消失,而不是立即消失
從下面這個博客得到啟示
畫鼠標流程
鼠標由PointerController.cpp控制。
文件在framework/base/libs/input/PointerController.cpp鼠標隱藏的方法
void PointerController::fade(Transition transition) {
AutoMutex _l(mLock);
// Remove the inactivity timeout, since we are fading now.
removeInactivityTimeoutLocked();
// Start fading.
if (transition == TRANSITION_IMMEDIATE) {
mLocked.pointerFadeDirection = 0;
mLocked.pointerAlpha = 0.0f;
updatePointerLocked();
} else {
mLocked.pointerFadeDirection = -1;
startAnimationLocked();
}
}復制代碼
本次補丁是framework/base/services/core/java/com/android/server/policy/PhoneWindowManaer.java+? ? Runnable HPHRunable = new Runnable(){
+? ?? ?? ?? ?public void run(){
+? ?? ?? ?? ?? ? mEscPressd = true;
+? ?? ?? ?? ?? ?Log.e(TAG,"linjc:HPHRunable");
+? ?? ?? ?? ?? ?mstate=SystemProperties.get("sys.KeyMouse.mKeyMouseState");
+? ?? ?? ?? ?? ?if(mstate.equals("on"))
+? ?? ?? ?? ?? ?{
+? ?? ?? ?? ?? ?? ?? ???SystemProperties.set("sys.KeyMouse.mKeyMouseState","off");
+? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Toast.makeText(mContext, "Restore the default button mode", Toast.LENGTH_LONG).show();
+? ?? ?? ?? ?? ?//? ?? ?? ?? ? Toast.makeText(getActivity(), "Restore the default button mode", Toast.LENGTH_LONG).show();
+? ?? ?? ?? ?? ?? ?? ? }
+? ?? ?? ?? ?? ?? ?? ? else
+? ?? ?? ?? ?? ?? ?? ? {
+? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?SystemProperties.set("sys.KeyMouse.mKeyMouseState","on");
+? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?Toast.makeText(mContext, "Into Mouse mode,click this key again out of this mode", Toast.LENGTH_LONG).show();
+? ?? ?? ?? ?? ?//? ?? ?? ?? ? Toast.makeText(getActivity(), "Into Mouse mode,click this key again out of this mode", Toast.LENGTH_LONG).show();
+? ?? ?? ?? ?? ?}
+? ?? ?? ?? ?}
+? ? };
+復制代碼他主要是設置sys.KeyMouse.mKeyMouseState這個全局屬性。
sys.KeyMouse.mKeyMouseState在interceptKeyBeforeDispatching函數里
@Override
public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
final boolean keyguardOn = keyguardOn();
final int keyCode = event.getKeyCode();
final int repeatCount = event.getRepeatCount();
final int metaState = event.getMetaState();
final int flags = event.getFlags();
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
if (DEBUG_INPUT) {
Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
+ repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
+ " canceled=" + canceled);
}
mstate = SystemProperties.get("sys.KeyMouse.mKeyMouseState");
if (mstate.equals("on") && ((keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_LEFT)
|| (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_RIGHT)
|| (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_UP)
|| (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_DOWN)
|| (keyCode == KeyEvent.KEYCODE_TV_KEYMOUSE_MODE_SWITCH))) {
keydown = down;
mKeyMouseHandler.sendEmptyMessage(keyCode);
//return -1;
}
if (mstate.equals("on") && ((keyCode == KeyEvent.KEYCODE_ENTER)
||(keyCode == KeyEvent.KEYCODE_DPAD_CENTER))) {
return -1;
}
...復制代碼當sys.KeyMouse.mKeyMouseState為on的時候,截取一些keycode交給mKeyMouseHandler處理
public Handler mKeyMouseHandler = new Handler() {
public void handleMessage(Message msg) {
switch(msg.what){
case KeyEvent.KEYCODE_TV_KEYMOUSE_LEFT:
mdeltax = -1.0f;
mdeltay = 0;
break;
case KeyEvent.KEYCODE_TV_KEYMOUSE_RIGHT:
mdeltax = 1.0f;
mdeltay = 0;
break;
case KeyEvent.KEYCODE_TV_KEYMOUSE_UP:
mdeltax = 0;
mdeltay = -1.0f;
break;
case KeyEvent.KEYCODE_TV_KEYMOUSE_DOWN:
mdeltax = 0;
mdeltay = 1.0f;
break;
case KeyEvent.KEYCODE_TV_KEYMOUSE_MODE_SWITCH:
mdeltax = 0;
mdeltay = 0;
break;
default:
break;
}
try {
mWindowManager.dispatchMouse(mdeltax,mdeltay,screenWidth,screenHeight);
} catch (Exception e){
e.printStackTrace();
}
if (keydown) {
mKeyMouseHandler.sendEmptyMessageDelayed(msg.what,30);
}
}
};復制代碼mWindowManager.dispatchMouse(mdeltax,mdeltay,screenWidth,screenHeight);
發現鼠標事件由這個方法處理。
mWindowManager是WindowManagerService
跟進dispatchMouse這個方法
framework/base/services/core/java/com/android/server/wm/WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
...
}
...
public void dispatchMouse(float x, float y, int w, int h) {
mInputManager.dispatchMouse(x,y,w,h);
}復制代碼mInputManager是InputManagerService類的實例
framework/base/services/core/java/com/android/server/input/InputManagerService.java
public void dispatchMouse(float x, float y, int w, int h){
nativedispatchMouse(x, y, w, h, mPtr);
}復制代碼
private static native void nativedispatchMouse(float x, float y, int w, int h, long ptr);復制代碼nativedispatchMouse是一個jni方法
查找framework/base/services/core/jni下
發現一個com_android_server_input_InputManagerService.cpp
framework/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static const JNINativeMethod gInputManagerMethods[] = {
/* name, signature, funcPtr */
...復制代碼nativedispatchMouse的原型是android_server_InputManager_nativedispatchMouse
static void android_server_InputManager_nativedispatchMouse(JNIEnv* env,
jclass clazz,jfloat x,jfloat y,jint w,jint h,jlong ptr) {
NativeInputManager* im = reinterpret_cast(ptr);
int mID;
float mx, my;
float screenWidth,screenHeight;
char *mgetID=new char[PROPERTY_VALUE_MAX];
char *mkeyMouseState=new char[PROPERTY_VALUE_MAX];
screenWidth=(float)w;
screenHeight=(float)h;
property_get("sys.ID.mID",mgetID,0);
mID=atoi(mgetID);
mPointerController=im->obtainPointerController(mID);
//start to dispatchMouse
mPointerController->setPresentation(
PointerControllerInterface::PRESENTATION_POINTER);
mPointerController->move(x,y);
mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
mPointerController->getPosition(&mx, &my);
//if((mx<=0)||((mx>=(screenWidth-10.0f))||(my<=0)||(my>=(screenHeight-10.0f)))
//? ?? ???x=0;y=0;
if (mx == 0) {
strcpy(mkeyMouseState, "left");
} else if (mx>=(screenWidth-5.0f)) {
strcpy(mkeyMouseState, "right");
} else if (my == 0) {
strcpy(mkeyMouseState, "up");
} else if (my >= (screenHeight-5.0f)) {
strcpy(mkeyMouseState, "down");
} else {
strcpy(mkeyMouseState, "Non-boundary");
}
property_set("sys.keymouselimitstate",mkeyMouseState);
}復制代碼終于在這里發現了PointerController的實例了
隱藏鼠標只要模仿dispatchMouse寫一個方法就可以了
static void android_server_InputManager_nativefadeMouse(JNIEnv* env,
jclass clazz,jlong ptr){
NativeInputManager* im = reinterpret_cast(ptr);
int mID;
char *mgetID=new char[PROPERTY_VALUE_MAX];
property_get("sys.ID.mID",mgetID,0);
mID=atoi(mgetID);
mPointerController=im->obtainPointerController(mID);
//start to dispatchMouse
mPointerController->setPresentation(
PointerControllerInterface::PRESENTATION_POINTER);
mPointerController->fade(PointerControllerInterface::TRANSITION_IMMEDIATE);
}復制代碼
gInputManagerMethods[] 數組加上我們新加的方法
{ "nativefadeMouse", "(J)V",
(void*) android_server_InputManager_nativefadeMouse},復制代碼第二個參數括號里面代表的是函數參數類型,括號外的表示返回類型,一定要對應。具體值百度。
這里要注意的是WindowManagerService是繼承了IWindowManager.Stub
要找到IWindowManager.aidl加上對應的方法。
最后,找到文件在
framework/base/core/java/android/view/IWindowManager.aidl
其他中間調用就不寫了。
-----------------------------------
鼠標顯示的方法
比較簡單,看到上面的mKeyMouseHandler。
當sys.KeyMouse.mKeyMouseState設為on的同時,將keydown設為true(為了讓鼠標一直顯示,直到模式切換回去或者有人按鍵),mKeyMouseHandler.sendEmptyMessage(KeyEvent.KEYCODE_TV_KEYMOUSE_MODE_SWITCH)。
總結
以上是生活随笔為你收集整理的android 隐藏鼠标光标,Android7.1下显示/隐藏鼠标的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android wear5.0,Andr
- 下一篇: Android 的座位图控件,用于电影票