温州网站建设接单网络营销方案策划
需求 : tv上部分app不支持光标选中,如亚马逊,插上鼠标不方便,即可以用遥控器模拟鼠标滚动和点击
1.拦截上下左右键
在WMS::PhoneWindowManager::interceptKeyBeforeQueueing中监听上下左右左右键,进行拦截。
@Overridepublic long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {//是否开启鼠标模式String mstate = SystemProperties.get("sys.KeyMouse.mKeyMouseState");//是否开启鼠标滚轮模式String mMode = SystemProperties.get("sys.mouse.mousemode1");if (mstate.equals("on") && ((keyCode == KeyEvent.KEYCODE_DPAD_LEFT)|| (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT)|| (keyCode == KeyEvent.KEYCODE_DPAD_UP)|| (keyCode == KeyEvent.KEYCODE_DPAD_DOWN))) {if(down){if (mMode.equals("false")) {try{// 显示鼠标键mWindowManager.dispatchMouse(0,0);}catch(Exception e){}} else {Message msg = new Message();msg.what = keyCode;Bundle bundle = new Bundle();bundle.putInt("repeatCount", repeatCount);msg.setData(bundle);mKeyMouseHandler.sendMessage(msg);}}return -1;}
}public Handler mKeyMouseHandler = new Handler(){public void handleMessage(Message msg){Bundle bundle = msg.getData();int repeatNum = bundle.getInt("repeatCount");switch(msg.what){case KeyEvent.KEYCODE_DPAD_LEFT:if(repeatNum>0){//移动的距离mdeltax=-16.0f;mdeltay=0;}else{mdeltax=-8.0f;mdeltay=0;}break;case KeyEvent.KEYCODE_DPAD_RIGHT://移动的距离if(repeatNum>0){mdeltax=16.0f;mdeltay=0;}else{mdeltax=8.0f;mdeltay=0;}break;case KeyEvent.KEYCODE_DPAD_UP://移动的距离if(repeatNum>0){mdeltax=0;mdeltay=-16.0f;}else{mdeltax=0;mdeltay=-8.0f;}break;case KeyEvent.KEYCODE_DPAD_DOWN://移动的距离if(repeatNum>0){mdeltax=0;mdeltay=16.0f;}else{mdeltax=0;mdeltay=8.0f;}break;case KeyEvent.KEYCODE_MOUSE_SWITCH://位置不变,重新显示mdeltax=0;mdeltay=0;break; }try{mWindowManager.dispatchMouse(mdeltax,mdeltay);}catch(Exception e){}}};
2.调整鼠标滚动逻辑
如果只需要鼠标上下移动,上述修改即可,鼠标移动到屏幕周围会自动切为滚动模式,但是如果部分app上下有部分导航栏,即需要主动将鼠标切为滚轮模式。
修改位置 frameworks/native/services/inputflinger/InputReader.cpp
void KeyMouseInputMapper::sync(nsecs_t when) {int32_t lastButtonState = mButtonState;int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();mButtonState = currentButtonState;char *mKeyLock=new char[PROPERTY_VALUE_MAX];memset(mKeyLock,0,5);property_get("sys.KeyMouse.mKeyMouseState",mKeyLock,"off");char *mousemode=new char[PROPERTY_VALUE_MAX];memset(mousemode,0,5);property_get("sys.mouse.mousemode1",mousemode,"true");bool scrolled = 0;float vscroll,hscroll;int32_t keystate = AKEY_STATE_UNKNOWN;bool wasDown = isPointerDown(lastButtonState);bool down = isPointerDown(currentButtonState);keystate = getScanCodeState(AINPUT_SOURCE_MOUSE,scrollkey);bool downChanged;if (!wasDown && down) {mDownTime = when;downChanged = true;} else if (wasDown && !down) {downChanged = true;} else {downChanged = false;}nsecs_t downTime = mDownTime;//int32_t buttonsPressed=0;//int32_t buttonsReleased=0;int32_t buttonsPressed = currentButtonState & ~lastButtonState;int32_t buttonsReleased = lastButtonState & ~currentButtonState;if(strcmp(mKeyLock,"off")==0) return;PointerProperties pointerProperties;pointerProperties.clear();pointerProperties.id = 0;pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;PointerCoords pointerCoords;pointerCoords.clear();int32_t displayId;if (mPointerController != NULL) {float x, y;float minX, minY, maxX, maxY;mPointerController->getPosition(&x, &y);pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);displayId = ADISPLAY_ID_DEFAULT;//滚动模式后,判断上下左右键即滚动if(strcmp(mousemode,"false")==0) {if(scrollkey == KEY_LEFT){scrolled = 1;vscroll = 0;hscroll = -3.0f;if(keystate==AKEY_STATE_DOWN)buttonsPressed = 1;elsebuttonsReleased = 1;}else if(scrollkey == KEY_UP){scrolled = 1;vscroll = 3.0f;hscroll = 0;}else if(scrollkey == KEY_RIGHT){scrolled = 1;vscroll = 0;hscroll = 3.0f;if(keystate==AKEY_STATE_DOWN)buttonsPressed = 1;elsebuttonsReleased = 1;}else if(scrollkey == KEY_DOWN){scrolled = 1;vscroll = -3.0f;hscroll = 0;}}else{if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {if((x<=minX)&&(scrollkey == KEY_LEFT)){scrolled = 1;vscroll = 0;hscroll = -3.0f;if(keystate==AKEY_STATE_DOWN)buttonsPressed = 1;elsebuttonsReleased = 1;}else if((y<=minY)&&(scrollkey == KEY_UP)){scrolled = 1;vscroll = 3.0f;hscroll = 0;}else if((x>=maxX)&&(scrollkey == KEY_RIGHT)){scrolled = 1;vscroll = 0;hscroll = 3.0f;if(keystate==AKEY_STATE_DOWN)buttonsPressed = 1;elsebuttonsReleased = 1;}else if((y>=maxY)&&(scrollkey == KEY_DOWN)){scrolled = 1;vscroll = -3.0f;hscroll = 0;}}}}uint32_t policyFlags = 0;if ((buttonsPressed || scrolled) && getDevice()->isExternal()) {policyFlags |= POLICY_FLAG_WAKE;}mSource = AINPUT_SOURCE_MOUSE;// Send motion event.if (downChanged || scrolled) {int32_t metaState = mContext->getGlobalMetaState();int32_t buttonState = lastButtonState;int32_t motionEventAction;if (downChanged) {motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;} else {motionEventAction = AMOTION_EVENT_ACTION_MOVE;}if (buttonsReleased) {BitSet32 released(buttonsReleased);while (!released.isEmpty()) {int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());buttonState &= ~actionButton;NotifyMotionArgs releaseArgs(when, getDeviceId(), mSource, policyFlags,AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,1, 1, downTime);getListener()->notifyMotion(&releaseArgs);buttonsReleased = 0;}}NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,motionEventAction, 0, 0,metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,displayId, 0, 1, &pointerProperties, &pointerCoords, 1, 1, downTime);getListener()->notifyMotion(&args);if (buttonsPressed) {BitSet32 pressed(buttonsPressed);while (!pressed.isEmpty()) {int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());buttonState |= actionButton;NotifyMotionArgs pressArgs(when, getDeviceId(), mSource, policyFlags,AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,1, 1, downTime);getListener()->notifyMotion(&pressArgs);buttonsPressed = 0;}}}if ((scrolled)&&(keystate==AKEY_STATE_DOWN)) {pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);int32_t metaState = mContext->getGlobalMetaState();NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, currentButtonState,AMOTION_EVENT_EDGE_FLAG_NONE,displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,1, 1, downTime);getListener()->notifyMotion(&scrollArgs);}}