简体   繁体   中英

Android Multitouch on 2.3.x

I'm working on a game and a basic requirement for multiplayer is multitouch (two buttons being pressed at the same time) . Without it, the game makes no sense. So I am trying to make it work properly for a few days and I came to some conclusions.

I will show my test class, if I make it work there, implementing that in my game is a piece of cake. User @jboi wrote me this piece of code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    Log.d("TEST", "Begin onCreate");
    super.onCreate(savedInstanceState);
    Log.d("TEST", "End   onCreate");

    setContentView(R.layout.test);
    findViewById(R.id.upperTouchable).setOnTouchListener(new MyTouchListener());
    findViewById(R.id.lowerTouchable).setOnTouchListener(new MyTouchListener());
}

private boolean lowerIsTouched = false;
private boolean upperIsTouched = false;

private void setInfo() {
    if(lowerIsTouched && upperIsTouched)
        ((TextView) findViewById(R.id.info)).setText("both touched");
    else if(lowerIsTouched)
        ((TextView) findViewById(R.id.info)).setText("only lower is touched");
    else if(upperIsTouched)
        ((TextView) findViewById(R.id.info)).setText("only upper is touched");
    else
        ((TextView) findViewById(R.id.info)).setText("non is touched");

    ((TextView) findViewById(R.id.lowerTouchable)).setText(lowerIsTouched? "touched":"not touched");
    ((TextView) findViewById(R.id.upperTouchable)).setText(upperIsTouched? "touched":"not touched");
}

private class MyTouchListener implements OnTouchListener {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN) {
            if(v.getId() == R.id.lowerTouchable)
                lowerIsTouched = true;
            else if(v.getId() == R.id.upperTouchable)
                upperIsTouched = true;
            setInfo();
        }
        else if(event.getAction() == MotionEvent.ACTION_UP) {
            if(v.getId() == R.id.lowerTouchable)
                lowerIsTouched = false;
            else if(v.getId() == R.id.upperTouchable)
                upperIsTouched = false;
            setInfo();
        }
        return true;
    }
}

Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/info"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:background="#FFFFFFFF"
android:text="Non touched"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
    android:id="@+id/upperTouchable"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:gravity="center"
    android:text="Not touched"
    android:background="#FFF0F0F0"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
    android:id="@+id/lowerTouchable"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:gravity="center"
    android:text="Not touched"
    android:background="#FFFFFFFF"
    android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

I have tested this on several devices. It works on: Htc One (4.2.2), Samsung Galaxy S4 (4.3), Samsung Galaxy S3(4.1.2.) (when i press both buttons -> both are pressed) It doesn't work on:Sony Xperia Arc S(2.3.4.) and Alcatel One Touch(2.3.6.) (when i press both buttons -> only the first button is pressed) So I came to conclusion that the android version where multitouch support starts is between 2.4 and 4.1, but that's not true, because it's been added in 2.2.

I have 24 hours to solve this. Optionally, I could make my app compatibile only with 4.0+, but I would really like to make it work on most Android phones. My question is: How do I make this code work on 2.3-4.1, because I'm sure it can work (other apps have functional multitouch on those phones). Completely rewriting my code is also an option. I have tried working with ACTION_POINTER_DOWN, that also failed on "lower version" phones. Thanks in advance.

first one, you need check if your device have support for multitouch, that is very important and the features configured. You can red this article.

You can check availability of the multitouch in the code:

if (Integer.parseInt(Build.VERSION.SDK) >= 7) {
    PackageManager pm = context.getPackageManager();
    boolean hasMultitouch = 
        pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH);
    if (hasMultitouch) {
        // set multitouch event listeners
    } else {
        // set zoom buttons
    }
} else {
    // set zoom buttons
}

You can get PackageManager from your activity (service) without using context: PackageManager pm = getPackageManager();

There are three types of multitouch you can check.

[FEATURE_TOUCHSCREEN_MULTITOUCH][2] - basic two-finger gesture detection.
[FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT][3] - tracking two or more fingers fully independently.
[FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND][4] - tracking a full hand of fingers fully independently - that is, 5 or more simultaneous independent pointers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM