最近开发过程中遇到一个问题:一个类似于微信语音的功能——长按按钮,然后弹出正在语音的对话框,开始说话。然后等说话完毕,松开手指,语音发送。但是在有些机子(国产)里面虽然在6.0以下,可能修改过rom,还有权限框弹出来。这就比较蛋疼了。当权限框弹出的时候,用户松开手指去点击确定,但是点击确定之后就会自动继续执行刚刚的ACTION_DOWN事件,页不会触发ACTION_UP事件了。刚开始我想通过检查权限来判定时是否执行ACTION_DOWN下面的事件,但是不论怎么检测都是有权限的,因为6.0以下只要在manifest里面注册就默认全部由权限了。
通过我的回忆(百度)之后,这里就要复习一下Android的事件传递了。在onTouch监听中有ACTION_CANCEL这么一个事件。这个事件什么时候会被触发呢?
当控件收到前驱事件(什么叫前驱事件?一个从DOWN一直到UP的所有事件组合称为完整的手势,中间的任意一次事件对于下一个事件而言就是它的前驱事件)之后,后面的事件如果被父控件拦截,那么当前控件就会收到一个CANCEL事件,并且把这个事件会传递给它的子事件。(注意:这里如果在控件的onInterceptTouchEvent中拦截掉CANCEL事件是无效的,它仍然会把这个事件传给它的子控件)之后这个手势所有的事件将全部拦截,也就是说这个事件对于当前控件和它的子控件而言已经结束了。
而遇到的这个问题解决方案就是在控件收到ACTION_DOWN的事件之后,在代码执行过程中,发生了权限询问,弹出对话框,此时会拦截之后的MOVE事件,从而直接发给控件CANCEL事件。只需要监听CANCEL事件后取消当前DOWN事件已经触发的代码执行。