Media file is played and overlay when i selected item - android

I have a application in which when i select any item then it will play that media file but when i select other item then the old media is playing continue and the current media file is overlay(current file is also playing) so i am listen both media files.
I have written below code:
ImageView songView;
Gallery songGallery;
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.song_test);
songView = (ImageView) findViewById(R.id.songView);
songGallery = (Gallery) findViewById(R.id.songGallery);
songGallery.setAdapter(new MyGalleryAdapter(getApplicationContext()));
songGallery.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View arg1,
int arg2, long id) {
// TODO Auto-generated method stub
songView.setImageResource(symbolIds[arg2]);
String imageName = getResources().getResourceEntryName(
symbolIds[arg2]);
Uri audio = Uri.parse("android.resource://" + getPackageName()
+ "/raw/" + imageName + "");
mp = MediaPlayer.create(getApplicationContext(), audio);
try {
if (mp.isPlaying()) {
mp.reset();
}
mp.start();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"Error", Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), e.toString(),
Toast.LENGTH_LONG).show();
}
....
....
}
}
So my question is - When i select the item the song is playing very well but when i select other item then the old song is also playing with the current.
so i want to stop the old song...
I want to play only current selected item song.

The issue is that MediaPlayer is being recreated instead of being reset. Rather than using the #create() factory call, you can use the constructor instead. In the following code, if the mp is already created it is reset and then a datasource is prepared and started.
if (mp != null) {
mp.reset();
} else {
mp = new MediaPlayer();
}
// Now set the datasource
mp.setDataSource(context, audio);
mp...
mp.prepare();
mp.start();
Ideally though you should call prepareAsync and have a callback onPrepare() call the actual mediaPlayer.start so that prepare does not block the main thread.
mp.setOnPreparedListener(this);
mp.setDataSource(..)
mp.prepareAsync();
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}

Make the MediaPlayer mp global variable private static. Better yet use Singleton instead of global

You could review the state diagram here
then review an implementation of that logic for recycle media player in the
media sample you can find in your SDK installation:
$SDK/.../src/com/android/sample/apis/media/MediaPlayerDemo_Video.java
and follow how the sample resets the player state before using it again

Related

Android MediaPlayer will not play different songs

I'm trying to use one MediaPlayer to play a number of songs in succession. The first song will play as needed, but afterwards, one particular song (the first song in alphabetic order) will play over and over again. I followed this: Android Mediaplayer play different songs after eachother
public void startPlayer(View view) {
game = new Game();
TextView textView = (TextView) findViewById(R.id.title);
// start first song
Music firstSong = game.getNextSong();
textView.setText(firstSong.getID());
mediaPlayer = MediaPlayer.create(view.getContext(), firstSong.getID());
// make sure rest of songs play
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
goToNextSong();
}
});
// actually start!
mediaPlayer.start();
}
public void goToNextSong() {
Music nextSong = game.getNextSong();
TextView textView = (TextView) findViewById(R.id.title);
// if we still have music to play
if (nextSong != null) {
try {
// set the new title
textView.setText(nextSong.getID());
mediaPlayer.stop();
mediaPlayer.reset();
// get the music file
FileDescriptor fd = getResources().openRawResourceFd(
nextSong.getID()).getFileDescriptor();
mediaPlayer.setDataSource(fd);
// play it!
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
Even when I set fd to a particular song, it will still play the first song in alphabetical order. nextSong.getID() returns R.raw.somesong. The textview (which is set to the song ID) changes to the correct song. Help?
So I haven't found a way to keep the same MediaPlayer and play different songs, so I just made a new one each time. It works!
public void startPlayer() {
game = new Game();
goToNextSong();
}
public void goToNextSong() {
Music nextSong = game.getNextSong();
TextView textView = (TextView) findViewById(R.id.title);
// if we still have music to play
if (nextSong != null) {
try {
// set the new title
textView.setText(nextSong.getID());
// stop old music player
if (mediaPlayer != null) {
mediaPlayer.stop();
}
// create new music player
mediaPlayer = MediaPlayer.create(textView.getContext(),
nextSong.getID());
// make sure rest of songs play
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
goToNextSong();
}
});
// actually start!
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
} else {
// we're done!
mediaPlayer.release();
mediaPlayer = null;
}
}

Play a sound from res/raw

I m making an app which is supposed to play a few sounds with the mediaPlayer.
This is the code i use :
String[] name = {"sonar_slow","sonar_medium","sonar_fast"};
String link = "/res/raw/" + name[state-1] + ".mp3";
try {
player.setDataSource(link);
player.prepare();
player.start();
} catch(Exception e) {
e.printStackTrace();
}
I also tried this :
if(state==1){
player.create(this, R.raw.sonar_slow);
}else if(state==2){
player.create(this, R.raw.sonar_medium);
}else if(state==3){
player.create(this, R.raw.sonar_fast);
}
player.start();
But none of the above is working. My app is not crashing but the sound is not playing.
Any ideas ?
There are two problems.
Problem 1
You cannot reference resources inside your projects /res/raw directory in this fashion. The file "/res/raw/sonar_slow.mp3" in your project directory is not stored in "/res/raw/sonar_slow.mp3" in your apk. Instead of the following:
MediaPlayer mp = MediaPlayer.create(this);
mp.setSource("sonar_slow");
You need to use
MediaPlayer mp = MediaPlayer.create(this, R.raw.sonar_slow);
Problem 2
The following is wrong: it calls a static method that does not modify the player.
player.create(this, R.raw.sonar_slow);
You should instead call
player = MediaPlayer.create(this, R.raw.sonar_slow);
Full solution
Below is a reusable AudioPlayer class that encapsulates MediaPlayer. This is slightly modified from "Android Programming: The Big Nerd Ranch Guide". It makes sure to remember to clean up resources
package com.example.hellomoon;
import android.content.Context;
import android.media.MediaPlayer;
public class AudioPlayer {
private MediaPlayer mMediaPlayer;
public void stop() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
public void play(Context c, int rid) {
stop();
mMediaPlayer = MediaPlayer.create(c, rid);
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
stop();
}
});
mMediaPlayer.start();
}
}
How to play a file with MediaPlayer:
MediaPlayer mp = MediaPlayer.create(this, R.raw.mysound); // sound is inside res/raw/mysound
mp.start();
This is a simple example of how to play a sound with the Android MediaPlayer.
You have two buttons hat each play a different sound. The selecting of the sound and actually playing it is done in the manageSound() method. The sounds "hello", "goodbye" and "what" are in the res/raw directory:
MediaPlayer mp = null;
String hello = "Hello!";
String goodbye = "GoodBye!";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Button buttonHello = (Button) findViewById(R.id.idHello);
buttonHello.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
managerOfSound(hello);
} // END onClick()
}); // END buttonHello
final Button buttonGoodBye = (Button) findViewById(R.id.idGoodBye);
buttonGoodBye.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
managerOfSound(goodbye);
} // END onClick()
}); // END buttonGoodBye
} // END onCreate()
protected void manageSound(String theText) {
if (mp != null) {
mp.reset();
mp.release();
}
if (theText.equals(hello))
mp = MediaPlayer.create(this, R.raw.hello);
else if (theText.equals(goodbye))
mp = MediaPlayer.create(this, R.raw.goodbye);
else
mp = MediaPlayer.create(this, R.raw.what);
mp.start();
}
Taken from here: http://www.badprog.com/android-mediaplayer-example-of-playing-sounds
Furthermore, I would strongly recommend using SoundPool instead of MediaPlayer, for better Performance and usability.
http://developer.android.com/reference/android/media/SoundPool.html
Please also check if your sound is muted - I know this sounds stupid, but it happens to the best of us ;)
You need to do it like this :
try{
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.start();
Make sure your only playing when the file has finished preparing.

Android MediaPlayer stops on onBackPressed

I have lots of problems with MediaPlayer.
It's likely pertaining to old OS versions, at least until 2.3.
One sound is playing fine in a certain Activity (right before launching another)
When I pop the second Activity to go back to the first one, I play the sound file right before the popping (I use super.onBackPressed).
On these old devices (~2.3), the sound file is cut off.
I use the same way of launching and playing the MediaPlayer.
I create the MediaPlayer using create (synched). I retain the MediaPlayer by putting it in a static container. I released end empty the container only on setOnCompletionListener. What's going on..
Here's some code...
// Start sound
adhocplaysoundstatic(R.raw.soundfile, getApplicationContext());
// Pop activity
super.onBackPressed();
Definition
static ArrayList<MediaPlayer> staticplayers = new ArrayList<MediaPlayer>();
static public void adhocplaysoundstatic(final int MEDIA, Context context) {
MediaPlayer player = getMediaPlayerStatic(MEDIA, context);
staticplayers.add(player); // Hold on to
player.setOnCompletionListener(new OnCompletionListener() {
#Override public void onCompletion(MediaPlayer mp) {
mp.release();
staticplayers.remove(mp);
}
});
player.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
Log.d(LOG_TAG, "onPrepared, play!");
mp.start();
}});
//player.start();
}
More...
static protected MediaPlayer getMediaPlayerStatic(int id, Context context) throws RuntimeException {
MediaPlayer player = MediaPlayer.create(context, id);
if (player == null) {
throw new RuntimeException("Failed creating media player from id " + id);
}
else {
player.setOnErrorListener(new OnErrorListener() {
#Override public boolean onError(MediaPlayer mp, int what, int extra) {
Log.d(LOG_TAG, "MediaPlayer error: " + mp.toString() + ", what: " + what + ", extra: " + extra);
return false;
}
});
}
return player;
}

Mediaplayer plays twice

I have a media player but when another file is selected it continues to play the old file and new one so it is playing two files at once here is my onCreate method
private MediaPlayer mediaplayer = new MediaPlayer();
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.songplaying);
// Getting Our Extras From Intent
Bundle names = getIntent().getExtras();
// Getting Specific Data
path = names.getString("pathkeyword");
//Start Player
try {
playAudio(path);
} catch (Exception e) {
e.printStackTrace();
}
and this is the method that plays the audio
private void playAudio(String url) throws Exception{
mediaplayer.release();
mediaplayer.setDataSource(url);
mediaplayer.prepare();
mediaplayer.start();
When you are start to play the song ,check it is playing or not and stop it if it is currently playing.
if(player.isPlaying())
{
mediaplayer.stop();
}
mediaplayer.reset();
mediaplayer.setDataSource(url);
mediaplayer.prepare();
mediaplayer.start();
no need to release the player.player.release() used only when player no longer needed .
And you have to use stop() and release() methods whenever activity destroys.Otherwise so many players are running in background.
Try to add this to oncreate method so you will be able to prevent the new creation of audio
Mediaplayer M = Mediaplayer.create(this,R.row.audio file)
and make a new function like
void my function {
// call it here
m.start();
}

Android MediaPlayer problems

I am triggering a MediaPlayer to play a sound on a button click. Sometimes, the player will play the whole sound, sometimes it will not. It always cuts off on the end. I read a few threads on here where people were having the same problem, but none of the suggestions worked. For example, someone said that adding a mediaPlayer.onCompletionListener() would fix the issue, but it has not.
Here is the code with the MediaPlayer:
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = inflater.inflate(R.layout.vocab_row, parent, false);
ImageView playIcon = (ImageView) row
.findViewById(R.id.blueplay_icon);
TextView vocabWord = (TextView) row
.findViewById(R.id.vocab_text_word);
TextView vocabMeaning = (TextView) row
.findViewById(R.id.vocab_text_meaning);
vocabWord.setText(data.get(position).getKey());
vocabMeaning.setText(data.get(position).getDefinition());
final String fileName = "audio/" + data.get(position).getAudio();
// set the click listener for the play button
playIcon.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final MediaPlayer player = new MediaPlayer();
AssetManager manager = SingleLesson.this.getAssets();
final AssetFileDescriptor descriptor;
try {
descriptor = manager.openFd(fileName);
long start = descriptor.getStartOffset();
long end = descriptor.getLength();
//reset player
if (player != null) {
player.reset();
}
player.setDataSource(descriptor.getFileDescriptor(),
start, end);
} catch (IOException e) {
Log.e("IO EXCEPTION: ", "while getting mp3 assets.");
e.printStackTrace();
}
// set volume
player.setVolume(100, 100);
try {
player.prepare();
} catch (IllegalStateException e) {
Log.e("ERROR: ", "media player, illegal state");
e.printStackTrace();
} catch (IOException e) {
Log.e("ERROR: ", "media player, IO exception");
e.printStackTrace();
}
player.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer inPlayer) {
player.start();
}
});
// called when the file is finished playing
player.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer player) {
player.stop();
player.release();
}
});
}
This problem is happening on the emulator but not my htc incredible. It also doesn't happen on my girlfriend's moto droid2, but the sounds do have "clicks" in them on the moto droid2.
How old is the emulator? I have seen issues with emulators files getting corrupt after some time. If it is not a new one, try creating a one.
I have couple suggestions for you. It might or might not work. MediaPlayer.prepare() is a synchronous method, that means it will complete before any other code down the line runs, so you don't need onPreparedListener to start the playback. you can just type MediaPlayer.start() below the prepare method. Other suggestion is since you wanna play the sound again and again you prolly dont wanna release the mediaplayer. Try putting the MediaPlayer.reset() method instead in the onCompletionListener. Hope it solves the problem. You can also try adding MediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); before the setDataSource method.
Thanks.

Categories

Resources