I tried writing code for multitouch but used images instead. Unfortunately, it won’t start. The code is correct: it has no errors. However, the log cat produces too many errors. Here are those errors. Thank you!
07-30 11:12:15.930: E/AndroidRuntime(642): FATAL EXCEPTION: main
07-30 11:12:15.930: E/AndroidRuntime(642): java.lang.RuntimeException: Unable to start activity ComponentInfo{sample.app.touchsample/sample.app.touchsample.TouchsampleActivity}: android.util.AndroidRuntimeException: requestFeature() must be called before adding content
07-30 11:12:15.930: E/AndroidRuntime(642): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
07-30 11:12:15.930: E/AndroidRuntime(642): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
07-30 11:12:15.930: E/AndroidRuntime(642): at android.app.ActivityThread.access$600(ActivityThread.java:130)
07-30 11:12:15.930: E/AndroidRuntime(642): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
07-30 11:12:15.930: E/AndroidRuntime(642): at android.os.Handler.dispatchMessage(Handler.java:99)
07-30 11:12:15.930: E/AndroidRuntime(642): at android.os.Looper.loop(Looper.java:137)
07-30 11:12:15.930: E/AndroidRuntime(642): at android.app.ActivityThread.main(ActivityThread.java:4745)
07-30 11:12:15.930: E/AndroidRuntime(642): at java.lang.reflect.Method.invokeNative(Native Method)
07-30 11:12:15.930: E/AndroidRuntime(642): at java.lang.reflect.Method.invoke(Method.java:511)
07-30 11:12:15.930: E/AndroidRuntime(642): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
07-30 11:12:15.930: E/AndroidRuntime(642): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-30 11:12:15.930: E/AndroidRuntime(642): at dalvik.system.NativeStart.main(Native Method)
07-30 11:12:15.930: E/AndroidRuntime(642): Caused by: android.util.AndroidRuntimeException: requestFeature() must be called before adding content
07-30 11:12:15.930: E/AndroidRuntime(642): at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:215)
07-30 11:12:15.930: E/AndroidRuntime(642): at android.app.Activity.requestWindowFeature(Activity.java:3225)
07-30 11:12:15.930: E/AndroidRuntime(642): at sample.app.touchsample.TouchsampleActivity.onCreate(TouchsampleActivity.java:190)
07-30 11:12:15.930: E/AndroidRuntime(642): at android.app.Activity.performCreate(Activity.java:5008)
07-30 11:12:15.930: E/AndroidRuntime(642): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
07-30 11:12:15.930: E/AndroidRuntime(642): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
07-30 11:12:15.930: E/AndroidRuntime(642): ... 11 more
package sample.app.touchsample;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Context;
import android.graphics.Path;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
//import android.widget.FrameLayout;
import android.widget.ImageView;
//import sample.app.touchsample.TouchsampleActivity.secondDrum.thirdDrum;
import android.widget.LinearLayout;
public class TouchsampleActivity extends Activity implements OnTouchListener
{
MediaPlayer mp;
SoundPool fx;
HashMap <Integer, Integer> fxMap;
int sfxId=1;
int sfxId2=2;
int sfxId3=3;
int sfxId4=4;
private Path path = new Path();
private View parent;
private final ArrayList[] recentTouchedViewsIndex = new ArrayList[10];
private final ArrayList[] downTouchedViewsIndex = new ArrayList[10];
private final ArrayList<View> moveOutsideEnabledViews = new ArrayList<View>();
private final ArrayList<View> multiTouchViews = new ArrayList<View>();
private int mTouchSlop = 24;
private static final String TAG = "Touch";
//private ImageView imageView1, imageView2 ;
public void addMoveOutsideEnabledViews(final View view) {
moveOutsideEnabledViews.add(view);
}
private void dealEvent(final int actionPointerIndex,
final MotionEvent event, final View eventView,
final int actionResolved) {
int rawX, rawY;
final int location[] = { 0, 0 };
eventView.getLocationOnScreen(location);
// Log.v("tag", location + "");
rawX = (int) event.getX(actionPointerIndex) + location[0];
rawY = (int) event.getY(actionPointerIndex) + location[1];
final int actionPointerID = event.getPointerId(actionPointerIndex);
ArrayList<View> hoverViews = getTouchedViews(rawX, rawY);
if (actionResolved == MotionEvent.ACTION_DOWN) {
downTouchedViewsIndex[actionPointerID] = (ArrayList<View>) hoverViews
.clone();
}
// deletes all views which where not clicked on ActionDown
if (downTouchedViewsIndex[actionPointerID] != null) {
final ArrayList<View> tempViews = (ArrayList<View>) hoverViews
.clone();
tempViews.removeAll(downTouchedViewsIndex[actionPointerID]);
hoverViews.removeAll(tempViews);
}
if (recentTouchedViewsIndex[actionPointerID] != null) {
final ArrayList<View> recentTouchedViews = recentTouchedViewsIndex[actionPointerID];
final ArrayList<View> shouldTouchViews = (ArrayList<View>) hoverViews
.clone();
if (!shouldTouchViews.containsAll(recentTouchedViews)) {
shouldTouchViews.removeAll(recentTouchedViews);
shouldTouchViews.addAll(recentTouchedViews);
final ArrayList<View> outsideTouchedViews = (ArrayList<View>) shouldTouchViews
.clone();
outsideTouchedViews.removeAll(hoverViews);
}
recentTouchedViewsIndex[actionPointerID] = hoverViews;
hoverViews = shouldTouchViews;
} else {
recentTouchedViewsIndex[actionPointerID] = hoverViews;
}
if (actionResolved == MotionEvent.ACTION_UP) {
recentTouchedViewsIndex[actionPointerID] = null;
downTouchedViewsIndex[actionPointerID] = null;
}
dumpEvent(event);
for (final View view : hoverViews) {
int x, y;
view.getLocationOnScreen(location);
x = rawX - location[0];
y = rawY - location[1];
// View does not recognize that the Pointer is
// outside if the Pointer is not far away (>mTouchSlop)
if (recentTouchedViewsIndex[actionPointerID] != null) {
if (pointInView(x, y, mTouchSlop, view.getWidth(),
view.getHeight())) {
// Log.v("tag", "added because < mTouchSlop");
if (!recentTouchedViewsIndex[actionPointerID]
.contains(view)) {
recentTouchedViewsIndex[actionPointerID].add(view);
}
} else if (moveOutsideEnabledViews.contains(view)) {
Log.v("tag", "outside but gets event");
recentTouchedViewsIndex[actionPointerID].add(view);
}
}
final MotionEvent me = MotionEvent.obtain(event.getDownTime(),
event.getEventTime(), actionResolved, x, y,
event.getPressure(actionPointerIndex),
event.getPressure(actionPointerIndex),
event.getMetaState(), event.getXPrecision(),
event.getYPrecision(), event.getDeviceId(),
event.getEdgeFlags());
me.setLocation(x, y);
if (!me.equals(event)) {
// deals the Event
view.onTouchEvent(me);
}
// debug
if (actionResolved == MotionEvent.ACTION_MOVE) {
Log.v("tag",
"#" + actionPointerIndex + " Rawx:" + rawX + " rawy:"
+ rawY + " x:" + x + " y:" + y + " "
+ view.toString());
}
}
}
// @Override
// public boolean onCreateOptionsMenu(Menu menu)
// {
// getMenuInflater().inflate(R.menu.touchsample, menu);
// return true;
// }
public class secondDrum implements OnTouchListener
{
public boolean onTouch(View v, MotionEvent event)
{
dumpEvent(event);
AudioManager bongos2 = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume2 = bongos2.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume2 = bongos2.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftvolume2 = curVolume2/maxVolume2;
float rightVolume2 = curVolume2/maxVolume2;
int priority2 = 1;
int no_loop2 = 0;
float normal_playback_rate2=1.0f;
fx.play(sfxId2, leftvolume2, rightVolume2, priority2, no_loop2, normal_playback_rate2);
return false;
}
}
public class thirdDrum implements OnTouchListener
{
public boolean onTouch(View v, MotionEvent event)
{
dumpEvent(event);
AudioManager bongos3 = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume = bongos3.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = bongos3.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftVolume = curVolume/maxVolume;
float rightVolume = curVolume/maxVolume;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 2.0f;
fx.play(sfxId3, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
return false;
}
}
public class forthDrum implements OnTouchListener
{
public boolean onTouch(View v, MotionEvent event)
{
dumpEvent(event);
AudioManager bongos4 = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume = bongos4.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = bongos4.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftVolume = curVolume/maxVolume;
float rightVolume = curVolume/maxVolume;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 2.0f;
fx.play(sfxId4, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
return false;
}
}
public boolean onTouch(View view, MotionEvent event)
{
dumpEvent(event);
AudioManager bongos = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume = bongos.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = bongos.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftVolume = curVolume/maxVolume;
float rightVolume = curVolume/maxVolume;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 1.0f;
fx.play(sfxId, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
//return false;
// index of the pointer which starts this Event
final int actionPointerIndex = event.getActionIndex();
// resolve the action as a basic type (up, down or move)
int actionResolved = event.getAction() & MotionEvent.ACTION_MASK;
if (actionResolved < 7 && actionResolved > 4) {
actionResolved = actionResolved - 5;
}
if (actionResolved == MotionEvent.ACTION_MOVE) {
for (int ptrIndex = 0; ptrIndex < event.getPointerCount(); ptrIndex++) {
// only one event for all move events.
dealEvent(ptrIndex, event, view, actionResolved);
Log.v("tag", "move" + ptrIndex);
}
} else {
dealEvent(actionPointerIndex, event, view, actionResolved);
}
return true;
}
private void dumpEvent(MotionEvent event)
{
final String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
final StringBuilder sb = new StringBuilder();
final int action = event.getAction();
final int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if(actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP)
{
sb.append("(pid " ).append(action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")" );
}
sb.append("[");
for (int i = 0; i <event.getPointerCount(); i++)
{
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if(i + 1 < event.getPointerCount())
sb.append(";");
}
sb.append("]");
Log.d(TAG, sb.toString());
}
private ArrayList<View> getChildViews(final View view) {
final ArrayList<View> views = new ArrayList<View>();
if (view instanceof ViewGroup) {
final ViewGroup v = ((ViewGroup) view);
if (v.getChildCount() > 0) {
for (int i = 0; i < v.getChildCount(); i++) {
views.add(v.getChildAt(i));
}
}
}
return views;
}
private ArrayList<View> getTouchedViews(final int x, final int y) {
View lastTouchedView = null;
//final ArrayList<View> touchedViews = new ArrayList<View>();
final ArrayList<View> possibleViews = new ArrayList<View>();
if (parent instanceof ViewGroup) {
possibleViews.add(parent);
for (int i = 0; i < possibleViews.size(); i++) {
final View view = possibleViews.get(i);
final int location[] = { 0, 0 };
view.getLocationOnScreen(location);
if (((view.getHeight() + location[1] >= y)
& (view.getWidth() + location[0] >= x)
& (view.getLeft() <= x) & (view.getTop() <= y))
|| view instanceof LinearLayout) {
if (this.multiTouchViews.contains(view)){
lastTouchedView = view;
}
possibleViews.addAll(getChildViews(view));
}
}
ArrayList<View> touchedViews = new ArrayList<View>();
if (lastTouchedView != null){
touchedViews.add(lastTouchedView);
}
return touchedViews;
}
return possibleViews;
}
//@Override
//public void onCreate(final Bundle instance) {
// super.onCreate(instance);
//public boolean onTouch(final View v, final MotionEvent event) {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.touchsample);
fx=new SoundPool(1100, AudioManager.STREAM_MUSIC, 1100);
fxMap=new HashMap<Integer, Integer>();
fxMap.put(sfxId, fx.load(this, R.raw.bongo_left, 1));
fxMap.put(sfxId2, fx.load(this, R.raw.bongo_right, 1));
fxMap.put(sfxId3, fx.load(this, R.raw.bongo_left, 1));
fxMap.put(sfxId4, fx.load(this, R.raw.bongo_right, 1));
ImageView view = (ImageView) findViewById(R.id.imageView1);
view.setOnTouchListener(this);
ImageView view2 = (ImageView) findViewById(R.id.imageView2);
view2.setOnTouchListener(new secondDrum());
ImageView view3 = (ImageView) findViewById(R.id.imageView3);
view3.setOnTouchListener(new thirdDrum());
ImageView view4 = (ImageView) findViewById(R.id.imageView4);
view4.setOnTouchListener(new forthDrum());
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
parent = findViewById(android.R.id.content).getRootView();
parent.setOnTouchListener(this);
mTouchSlop = ViewConfiguration.get(getApplicationContext())
.getScaledTouchSlop();
}
private boolean pointInView(final float localX, final float localY,
final float slop, final float width, final float height) {
return localX >= -slop && localY >= -slop && localX < ((width) + slop)
&& localY < ((height) + slop);
}
}
Remove these lines from where you have added it,
It has to be added in the onCreate() as soon you call the super class..
Even before you call the
setContentView(). Like the above snippet.