Android中关于APK对遥控器支持的修改

最近,对Andoid中APK做了一些修改,让其支持遥控器的支持,这把人弄得焦头烂额,好不郁闷,这里特别记录下思路,留给有需要的同志。

其实Android本身是做了对遥控器的上下左右按键的焦点移动控制,以及对Enter键的响应,现在知道的原因就是1:View的子类在派生时对其动作做了从写,导致其焦点控制失效;2:不明原因导致焦点控制失败。该文只是从功能上总结了自己在APK的IR修改中摸索出的一些方法,来达到支持IR控制的效果。

思路一:android提供了一些焦点相关的属性,在现有的框架层下通过设置View的属性来获得焦点

android:focusable:设置一个控件能否获得焦点android:background:设置在作为背景的drawableandroid:nextFocusDown:定义下一个获得焦点的控件当按下键时android:nextFocusUp:定义下一个获得焦点的控件当按上键时android:nextFocusLeft:定义下一个获得焦点的控件当按左键时android:nextFocusRight:定义下一个获得焦点的控件当按右键时<requestFocus/>:强制设置一个焦点到指定的view或它的一个子类,前提是android:focusable为true能够获得焦点

实例一:

<ImageButtonandroid:id="@+id/close" android:focusable="true" android:nextFocusDown="@+id/url" android:background="?android:attr/selectableItemBackground"android:layout_width="wrap_content"android:layout_height="wrap_content"android:contentDescription="@string/accessibility_button_closetab"android:src="@drawable/ic_tab_close" />

实例二:

<EditText android:id="@+id/user_dictionary_add_word_text"…………android:imeOptions="flagNoFullscreen"><requestFocus /> </EditText>

public boolean dispatchKeyEvent (KeyEvent event) public boolean onKeyDown (int keyCode, KeyEvent event)public boolean onKeyUp(int keyCode, KeyEvent event)public boolean dispatchKeyEventPreIme (KeyEvent event)public boolean onKeyPreIme (int keyCode, KeyEvent event)

实例一:

@Overridepublic boolean onKeyUp(int keyCode, KeyEvent event){ActivityState topState = getStateManager().getTopState();if(topState == null){return super.onKeyUp(keyCode, event);} /*显式调用ActivityState的onKeyUp事件处理,这个onKeyUp可以是重写View的消息处理,不是View 的话也可以自定义这个函数来进行事件处理,当然在这里你可以直接switch keyCode来进行当前Activity 事件处理*/if(topState.onKeyUp(keyCode, event)){return true;}else{return super.onKeyUp(keyCode, event);}}@Overridepublic boolean onTouchEvent(MotionEvent ev){ActivityState topState = getStateManager().getTopState();if(topState == null){return super.onTouchEvent(ev);}if(topState.onTouchEvent(ev)){return true;}else{return super.onTouchEvent(ev);}}/*在按键事件的分发时期进行拦截,做一些自己想做的处理*/@Overridepublic boolean dispatchKeyEvent (KeyEvent event){int keyCode = event.getKeyCode();ActivityState topState = getStateManager().getTopState();if(topState == null){return super.dispatchKeyEvent(event);}//sometimes even the actionbar is hide,but the input focus is on the actionbar,so when the focus is on//the slot,we should intercept the enterkeyevent action from the systemif(event.getAction() == KeyEvent.ACTION_UP){if(topState.getFocusOnSlotView()&& keyCode == KeyEvent.KEYCODE_ENTER){return topState.onKeyUp(keyCode, event);} }return super.dispatchKeyEvent(event);}@Overridepublic boolean dispatchTouchEvent (MotionEvent ev){ActivityState topState = getStateManager().getTopState();if(topState == null){return super.dispatchTouchEvent(ev);}if(ev.getAction() == MotionEvent.ACTION_DOWN){//if the user control the gallery by mouse,you should clear the focus recttopState.setFocusOnSlotView(false);}return super.dispatchTouchEvent(ev);}

实例二:

@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {final int uniChar = event.getUnicodeChar();final boolean handled = super.onKeyDown(keyCode, event);final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);if (!handled && acceptFilter() && isKeyNotWhitespace) {boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,keyCode, event);if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {return onSearchRequested();}}// Eat the long press event so the keyboard doesn’t come up.if (keyCode == KeyEvent.KEYCODE_MENU && event.isLongPress()) {return true;}return handled;}public void setOnKeyListener (View.OnKeyListener l)public boolean dispatchKeyEvent (KeyEvent event) public boolean dispatchKeyEventPreIme (KeyEvent event)

实例一:

OnKeyListener mCheckboxKeyListenner = new OnKeyListener(){public boolean onKey(View v, int keyCode, KeyEvent event){return onKeyDone(v, keyCode, event);}};public boolean onKeyDone(View v, int keyCode, KeyEvent event) {CollectCurrentSelected();if(event.getAction() == KeyEvent.ACTION_UP){return moveIndexOnKeyUp(keyCode);}if(event.getAction() == KeyEvent.ACTION_DOWN){return moveIndexOnKeyDown(keyCode);}return false;}private boolean moveIndexOnKeyUp(int keyCode){if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){if(mResponseIndex == INDEX_SETTINGBTN){return true;}}return false;}private boolean moveIndexOnKeyDown(int keyCode){if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT|| keyCode == KeyEvent.KEYCODE_DPAD_UP|| keyCode == KeyEvent.KEYCODE_DPAD_DOWN){mResponseIndex = INDEX_CHECKBOX;resetDefaultBackground();return false;}else if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){if(mResponseIndex == INDEX_SETTINGBTN){mResponseIndex = INDEX_CHECKBOX;resetDefaultBackground();return false;}else{mResponseIndex = INDEX_SETTINGBTN;mSettingBtn.setBackgroundResource(R.drawable.appwidget_item_bg_pressed);mSettingBtn.invalidate();mTextLayout.setBackgroundResource(R.drawable.appwidget_item_bg_normal);mTextLayout.invalidate();return true;}}else if(keyCode == KeyEvent.KEYCODE_ENTER){if(mResponseIndex == INDEX_CHECKBOX){checkBoxOption();}else if(mResponseIndex == INDEX_SETTINGBTN){startShowSetting();}return true;}else{return false;}}/*一般View的话,可以直接XXX. setOnKeyListener(XXX),在Setting中大量的用到PreferenceFragment,其内部镶嵌了一个listview,因此对一个PreferenceFragment的操作,其实是对该listview的操作,所以需要设这该listview的keyListener*/ListView listView = getListView();listView.setOnKeyListener(mCheckboxKeyListenner);

step 2:在能捕获按键之后,需要做的自己来做焦点的逻辑管理

看天,看雪,安安静静,不言不语都是好风景。

Android中关于APK对遥控器支持的修改

相关文章:

你感兴趣的文章:

标签云: