1.背景
近期公司买了一款第三方的对讲机,android系统9.0,用于给公司员工平时日常工作交流使用,介于员工年龄偏大,希望将对讲机上的一些方便的物理按键拦截,并设置成播放语音,快捷接单等功能(息屏状态下)
2.技术难点
如果是亮屏的状态,完全可以用onkeydown拦截到很多按键,除了home键和电源键,比如像这样:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
String devicesBtnName = "当前按键keyCode:" + keyCode + " ---- ";
Log.d(TAG, "keyCode : " + keyCode);
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
devicesBtnName += "返回键";
break;
case KeyEvent.KEYCODE_MENU:
devicesBtnName += "菜单键";
break;
case KeyEvent.KEYCODE_CALL:
devicesBtnName += "拨打电话键";
break;
。。。
而home键和电源键也可以使用广播来监听,其中要注意的是home键有事件可以监听,但是电源键没有,所以有取巧的方式根据屏幕 明、暗来判断;
3.我的设备
我们对接的第三方设备还有快捷拍照,快捷播放视频,p1 p2上下翻页等一般手机没有的物理按键按键,息屏状态下,产品需要将
1.快捷拍照改成播放订单语音;
2.播放视频改成快捷接单;
根据和对讲机厂商技术沟通,这些多出来的物理按键有些是电源键关闭直接掐断,有些依然能发出广播,这个厂商是可以支持修改的,刚好当前的系统1和2两个按键支持息屏广播。
那么这些定制按键广播的action是什么?都知道我们需要注册action,才能监听到这个事件,其实这个需要厂商提供,因为这些按键不属于android系统原生,类似
IntentFilter screenStatusIF = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
screenStatusIF.addAction(Intent.ACTION_SCREEN_ON);
screenStatusIF.addAction(Intent.ACTION_SCREEN_OFF);
这种系统Intent里面就有的,你可以直接找到,但是厂商定制的这里面是没有的,需要找厂商要类似
com.xxx.xxx.Action_XXX_XXX
String的action,然后注册广播给加进去,这样
screenStatusIF.addAction(”com.xxx.xxx.Action_XXX_XXX“)
你就能在广播里面监听到物理按键的点击,这里你可以根据action判断是哪个按键
public class ScreenStatusReceiver extends BroadcastReceiver {
String SCREEN_ON = "android.intent.action.SCREEN_ON";
String SCREEN_OFF = "android.intent.action.SCREEN_OFF";
@Override
public void onReceive(Context context, Intent intent) {
Log.i("ScreenStatusReceiver", intent.getAction());
if (SCREEN_ON.equals(intent.getAction())) {
Log.w("ppp", "ppp-屏幕亮了");
} else if (SCREEN_OFF.equals(intent.getAction())) {
Log.w("ppp", "ppp-屏幕暗了");
}
}
}
4.其他
说说除了广播和activity里面的onkeydown这种方式,还有一种无障碍功能,这个主要是利用服务监听物理按键
extends AccessibilityService {
写一个类继承AccessibilityService,这里面可以实现OnKeyDown方法,然后就是监听即可,但是这个监听物理按键也是有瑕疵的,按了电源键息屏依然获取不到,只是比activity中实现限制更小了,毕竟是个后台服务,app不管哪个界面都能监听到,包括锁屏状态(非息屏)
感兴趣的可以看看 这是我之前看过的一篇文章,一般这个都是用来做模拟物理按键的,
链接: Android进阶——Android无障碍服务
ps:用这个需要手机系统设置,开启无障碍模式,否则是不生效的