Android(安卓)TV热键(快捷键、组合键)实现
16lz
2021-01-26
TV上一些特殊的功能入口、串口打印开关、adb调试开关、部分菜单的显示隐藏等都可以通过热键来控制。
一般组合键选用某个功能键+一串数字即可,我们可以将其封装成工具类,这里快捷键,我使用F1和几个数字键组合。
public class SpecialKey implements Constants { private static SpecialKey instance = null; private Context mContext; private SpecialKeyCallBack mSpecialKeyCallBack; private StringBuffer strBuffer; private boolean hasSpecialKeyCode = true; private SpecialKey(Context context) { mContext = context; initData(); } public synchronized static SpecialKey getInstance(Context context) { if (instance == null) { instance = new SpecialKey(context); } return instance; } private void initData() { strBuffer = new StringBuffer(); strBuffer.setLength(0); } public void setInputKeyNumber(int keyCode, KeyEvent event) { int iDigital; switch (keyCode) { case KEY_0: iDigital = 0; break; case KEY_1: iDigital = 1; break; case KEY_2: iDigital = 2; break; case KEY_3: iDigital = 3; break; case KEY_4: iDigital = 4; break; case KEY_5: iDigital = 5; break; case KEY_6: iDigital = 6; break; case KEY_7: iDigital = 7; break; case KEY_8: iDigital = 8; break; case KEY_9: iDigital = 9; break; default: iDigital = -1; break; } if (iDigital != -1) { strBuffer.append(String.valueOf(iDigital)); setSpecialMenu(strBuffer); } } private void setSpecialMenu(StringBuffer strBuffer) { int iNumber = Integer.parseInt(strBuffer.toString()); switch (iNumber) { case 000: // patch_enable break; case 111: // show uart break; case 222: // show SDSMenu break; case 333: // ChangeLauncher(); break; case 987: // updateNetUpdateEnableStatus(); break; case 135: break; case 789: // PowerReboot break; case 8280: break; case 12500: // adb switcher break; case 12459: // print switcher break; case 8281: // PatchMenu break; case 234: // sendPVRRecTP(); break; default: hasSpecialKeyCode = false; break; } setDataClear(); } public void setDataClear() { strBuffer.setLength(0); if (mSpecialKeyCallBack != null) { mSpecialKeyCallBack.onChangeSpecialKeyStatus(false); mSpecialKeyCallBack.dismissNoChannelDLG(hasSpecialKeyCode); hasSpecialKeyCode = true; } } public void setSpecialKeyListener(SpecialKeyCallBack finish) { this.mSpecialKeyCallBack = finish; } public interface SpecialKeyCallBack { void onChangeSpecialKeyStatus(boolean status); void dismissNoChannelDLG(boolean isDismiss); }}
如何使用呢?一般,我们在电视应用主界面调用上面的工具类
步骤1:重写主界面Activity的onKeyDown()方法,将数字按键事件封装成一个方法,如果是F1按键,则实例化上述的热键工具类,并使用Handler发送一个热键消息。
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (onChangePIPKey(keyCode, event)) { return true; } if (onChangePVRKey(keyCode, event)) { return true; } if (isNumberKeyDown(keyCode, event)) { return true; } switch (keyCode) { case KEY_F1: Log.d(CLASS_NAME, "bSpecialKey = " + bSpecialKey); if (!bSpecialKey) { bSpecialKey = true; mSpecialKey = SpecialKey.getInstance(HomeActivity.this); mSpecialKey.setSpecialKeyListener(this); if (handler.hasMessages(RESPONSE_SPECIAL_KEY_DOWN)) { handler.removeMessages(RESPONSE_SPECIAL_KEY_DOWN); } handler.sendEmptyMessageDelayed(RESPONSE_SPECIAL_KEY_DOWN, 5000); } else { } break; default: break; } Log.d(CLASS_NAME, " " + event.getAction()); return super.onKeyDown(keyCode, event); }
步骤二:在数字按键处理函数中,如果需要处理热键,则将数字按键事件交给热键工具类的setInputKeyNumber()方法处理,否则将该事件还给主界面。
private boolean isNumberKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KEY_0: case KEY_1: case KEY_2: case KEY_3: case KEY_4: case KEY_5: case KEY_6: case KEY_7: case KEY_8: case KEY_9: if (bSpecialKey) { mSpecialKey.setInputKeyNumber(keyCode, event); } else { numberKeyDown(keyCode, event); } return true; default: break; } return false; }
步骤3:处理热键消息,实现Handler.Callback的handleMessage()方法。
@Override public boolean handleMessage(Message msg) { switch (msg.what) { case RESPONSE_POWER_ACTION: // handle power key break; case RESPONSE_SPECIAL_KEY_DOWN: if (bSpecialKey) { bSpecialKey = false; mSpecialKey.setDataClear(); } break; default: break; } return false; }
步骤4:主界面实现SpecialKeyCallBack两个回调方法。
@Override public void onChangeSpecialKeyStatus(boolean status) { bSpecialKey = status; } @Override public void dismissNoChannelDLG(boolean isDismiss) { if (isDismiss) { dismissDialogInner(NO_CHANNEL_DLG); isNoChannelDLGDismiss = isDismiss; } }
bSpecialKey这个变量用于判断是否需要处理热键,初始化置为false.
更多相关文章
- 安卓开发学习之解决JS不能调用Android方法
- Android(安卓)v22.0.1+ 关联 libs/*.jar 源码包的方法
- Android中使用Bundle交换数据
- LayoutInflater的用法
- Android(安卓)DataBinding & MVVM
- 【Android】快速切换到主线程更新UI的几种方法
- Android系统使用global key 一键启动指定APP或者打开WiFi/蓝牙等
- Android(安卓)N Settings 架构剖析
- Android(安卓)四大组件流程、Handler、AsyncTask、IntentService