pointerIndex超出Android多点触控范围

时间:2011-08-02 22:07:19

标签: java android exception multi-touch

我有一个触摸事件异常导致我的游戏在平板电脑上崩溃(或者更具体地说,蜂窝状)......我的手机上的游戏工作正常,我没有听说过任何不是这样的人运行Android 3.0或更高版本。这是相关的日志信息......

E/AndroidRuntime(26487): java.lang.IllegalArgumentException: pointerIndex out of range
E/AndroidRuntime(26487):    at android.view.MotionEvent.nativeGetAxisValue(Native Method)
E/AndroidRuntime(26487):    at android.view.MotionEvent.getX(MotionEvent.java:1549)
E/AndroidRuntime(26487):    at kieran.android.asteroids.GameUI.onTouchEvent(GameUI.java:665)
E/AndroidRuntime(26487):    at android.view.View.dispatchTouchEvent(View.java:4616)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1560)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1291)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1560)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1291)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1560)
E/AndroidRuntime(26487):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1291)

...这是调用它的代码。对我来说似乎很好,但也许蜂窝中有一个尚未修复的错误?上面日志中的行号665对应于float x = event.getX(id);行。它必须与我得到which变量的方式有关?但它在手机上运行良好/ 2.3及更低......

int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;

if(actionCode == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_UP) {
    int which = action >> MotionEvent.ACTION_POINTER_ID_SHIFT;
    int id = event.getPointerId(which);
    float x = event.getX(id);
    float y = event.getY(id);

我将非常感谢任何帮助/想法,因为我也想让平板电脑用户使用我的游戏。感谢。

6 个答案:

答案 0 :(得分:49)

我的问题是它实际上在实际上没有两个id时调用event.getX(1)。所以我确保event.getPointerCount()> = 2有两个ID,现在它可以工作了。也许你会有同样的运气!

答案 1 :(得分:7)

你遗漏了一些东西,你需要将面具应用到指针,否则你在技术上不会访问你认为你手指的ID

int action = event.getAction() & MotionEvent.ACTION_MASK;     
int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
int pointerId = event.getPointerId(pointerIndex);

答案 2 :(得分:1)

只需将getPointerId()更改为findPointerIndex()即可。也许将geAction()更改为getActionMasked()

希望它有所帮助!

答案 3 :(得分:1)

我也有这个错误,但在我的工作日期之前没有解决方案。对我有用的唯一临时伪修复是对 IllegalArgumentException 使用 try-catch

根据Android Issue 18990,它与ScaleGestureDetector有关,并且几天前已经提交了修复程序。

答案 4 :(得分:1)

当getX和getY使用指针索引时,原始发布使用指针ID。

当您使用ID进行单次触摸时,它似乎有效,因为id和索引都是0.如果您使用多点触控,那将会搞乱,因为索引可以更改。

示例:

触摸1向下。
触摸1状态索引= 0。 ID = 0

触摸2向下。
触摸1状态索引= 0。 ID = 0
触摸2状态索引= 1。 ID = 1

触摸1释放。
触摸2状态索引= 0 。 ID = 1个

请尝试以下代码:

final int action = e.getAction();       
final int pointerIndex =(action & MotionEvent.ACTION_POINTER_INDEX_MASK) 
                >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;      
float x = event.getX(pointerIndex);
float y = event.getY(pointerIndex);

答案 5 :(得分:0)

对于那些仍在寻找答案的人,请注意,当您使用带有缩放缩放的任何 ViewPager 时,也会发生这种情况。图像中的特征等。然后有可能您也可以获取此Exception。

解决方案

扩展现有的 ViewPager ,并使用try catch覆盖这些方法。

@Override
public boolean onTouchEvent(MotionEvent ev) {
    try {
        return super.onTouchEvent(ev);
    } catch (IllegalArgumentException ex) {
        ex.printStackTrace();
    }
    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    try {
        return super.onInterceptTouchEvent(ev);
    } catch (IllegalArgumentException ex) {
        ex.printStackTrace();
    }
    return false;
}