3

I want to play a gun shot sound continuously by onTouch. I am doing this for automatic gun sounds. So i have problem with there is delay in sound looping. which does not give real automatic gun sound effect. My main point is there should no delay when sound is playing again and again. My code is.

public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        mediaPlayer = MediaPlayer.create(RipleFire.this,
                sounds[position]);
        // if (mediaPlayer != null && mediaPlayer.isPlaying()) {
        // mediaPlayer.stop();
        // }
        try {
            mediaPlayer.prepare();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        imgflag.setImageResource(pistols[position]);

        imgflag.setImageResource(pistolsAnimations[position]);
        mediaPlayer.start();
        mediaPlayer.setLooping(true);

    } else if (event.getAction() == MotionEvent.ACTION_UP) {
        mediaPlayer.stop();
        mediaPlayer.reset();
        mediaPlayer.release();
        imgflag.setImageResource(pistols[position]);
    }

    return true;
}
kupendra
  • 1,002
  • 1
  • 15
  • 37
Rayyan
  • 186
  • 2
  • 11

4 Answers4

2

Their have may solution according to your question method-1 simply you can override on touch method by touching sound is started.

    @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mPlayer.setLooping(true);
                    mPlayer.start();
                    break;
                case MotionEvent.ACTION_UP:
                    mPlayer.pause();
                    break;
                }
                return true;
            }
    //or
    public boolean onTouch(View v, MotionEvent me) {
    switch(me.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if(!mPlayer.isPlaying()) mPlayer.start();
            break;
        case MotionEvent.ACTION_UP:
            if(mPlayer.isPlaying()) mPlayer.stop();
            break;
    }
}

method-2 you can also use runnable tread or run method

Boolean IsPressed = false;
Button mbtn = (Button) findViewById(R.id.mbtn);

then add a thread, in the method run add this code

@Override
public void run(){
      while(!btnIsPressed){
          myfunction();
      }
}

now, in method onCreate , add a listener to change value of the boolean to true e.g like this

mbtn.addOnClickListener( new OnClickListener(){

   @Overrride
   public void onClick(View v){
      btnIsPressed = true;
   }
});

Edited: i have include another method-3 here we run a thread whenever you touch view, it check isPress or not if view is touched then sound is repeated until unless when you release view from touch.

here i posted whole code for you answer

public class Soundstuff extends Activity implements OnTouchListener {
    SoundPool sP;
    boolean isPress = false;
    int gunshot = 0;
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        View v = new View(this);
        setContentView(v);

        v.setOnTouchListener(this);

        sP = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
        gunshot = sP.load(this, R.raw.gunshot, 1);

    }

    private Runnable runnable = new Runnable() {

        @Override
        public void run() {
            /* do what you need to do */
            if (isPress) {
                sP.play(gunshot, 1, 1, 0, 0, 1);
                /* and here comes the "trick" */
                handler.postDelayed(this, 300);
            } else {
            }
        }
    };

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            isPress = true;
            handler.postDelayed(runnable, 300);
            break;

        case MotionEvent.ACTION_UP:
            isPress = false;
            handler.postDelayed(runnable, 300);
            break;
        }

        return true;
    }
}

hope this will solve your problem.

Attaullah
  • 3,856
  • 3
  • 48
  • 63
2

use SoundPool instead of MediaPlayer.

SoundPool sP = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
gunshot = sP.load(this, R.raw.gunshot, 1);
sP.play(gunshot, 1, 1, 0, 0, 1);
1

you can use SoundPool instead of MediaPlayer for better performance.

  • SoundPool play sound imidiatly.
  • you can play 3+ sounds in parallel.
  • We make use of the setRate across it's full range [0.5f-2.0f].

for sounds like gunshoot, or knocking door sound etc, use SoundPool cause it has a lot advantages as compare to MediaPlayer. http://developer.android.com/reference/android/media/SoundPool.html http://examples.javacodegeeks.com/android/android-soundpool-example/

Sajidkhan
  • 608
  • 7
  • 16
0

agree with @haresh : try this one ..

runOnUiThread(new Runnable() {
                    public void run() {

                        if (pd.isShowing()) {

                            pd.dismiss();
                        }
                        Toast.makeText(getApplicationContext(), "" + msg,
                                Toast.LENGTH_LONG).show();

                    }
                });

here I m closing progress dialog and display some msg on screen .you can start or stop your media player like this way .

Radhey
  • 2,139
  • 2
  • 24
  • 42
  • 1
    declare your mp object outside of event Actions rather then inside and just start and stop as per you want inside different actions ,and another thing was that try onPause() rather than onStop() method . – Radhey Nov 22 '14 at 06:54
  • Still the same problem – Rayyan Nov 22 '14 at 06:59