上午测试报了一个bug:说是一只手指拖动虚拟摇杆上的View滑块不松,另一只手指点击Home键将App压后台,重新进入的时候,View滑块卡死了。
刚开始看到这个问题感觉很奇怪,因为正常情况下,手指离开屏幕,收到ACTION_UP事件后,滑块肯定是会返回中心点的。但是这种情况很明显就是没有收到ACTION_UP事件。后来在代码中打印了下Log,证实了我的想法。
那既然收不到ACTION_UP事件,我自己模拟一个ACTION_UP事件发给这个摇杆View就好了。
解决办法:
1.监听用户点击Home键的动作
android上监听Home键与Back键还不一样,不能在onKeyDown方法中去处理,必须要注册一个广播才能监听到Home键:
private void registerHomeReceiver(){ IntentFilter homeFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); registerReceiver(homePressReceiver, homeFilter); } //HOME键监听 private BroadcastReceiver homePressReceiver = new BroadcastReceiver() { final String SYSTEM_DIALOG_REASON_KEY = "reason"; final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String action = intent.getAction(); if(action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)){ String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY); System.out.println("reason : " + reason); if(reason!=null&&reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)){ System.out.println("按HOME键使应用进入了后台"); } } } };
需要注意的是,在Android8.0上最好使用动态广播的方式来注册,使用静态广播有时候会收不到消息。
另外,该广播除了能监听点击Home键外,还可以监听长按home键,以及按锁屏事件等,甚至是Activity切换的按键。
2.当用户点击Home键后,手动模拟一个ACTION_UP事件发送给指定的View
private void sendTouchUpEvent2RockerView() { long downTime = SystemClock.uptimeMillis(); long eventTime = SystemClock.uptimeMillis() + 100; float x = 0.0f; float y = 0.0f; int metaState = 0; MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, metaState); mLeftControllerView.dispatchTouchEvent(event); mRightControllerView.dispatchTouchEvent(event); }
然后在广播接收者中去处理:
case Intent.ACTION_CLOSE_SYSTEM_DIALOGS: String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY); if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) { sendTouchUpEvent2RockerView(); } break;
完了之后试了一下,果然没有了先前的问题。
参考链接:
android MotionEvent.obtain模拟事件,自动触发