mediaPlayer.release() crashes my app java - java

I have a project where I added a MediaPlayer in a custom Array Adapter and I make it take the Resource ID of the audio file from the Array List the problem is that I want to release the media player after the audio completes but every time I try to add release in OnCompletion and try to press a view while the media player plays a sound the app crashes .. I searched online and found a code but it gives me an error and I can't find the actual reason for such a crash.
that's the code for the on Click Listener and the Media player:
final MediaPlayer mediaPlayer = MediaPlayer.create(getContext(), currentWord.getVoiceResourceID());
// Wait for user's input by his click on the list's item to play the sound.
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// Storing the return value of getVoiceResourceID() into mVoice.
// I think this line can be ignored so we call the method inside the creation of the Media Player.
// Creating our media player and put our track on it.
mediaPlayer.selectTrack(currentWord.getVoiceResourceID());
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer.release();
}
});
}
};
I hope I could fix that problem.

Related

Android Studio Mediaplayer

I am a completely begginer guy in Android Studio and mobile apps in general. I used to create websites on Wordpress and i don't have so much experience on coding. Recently i started experimenting with mobile apps and mostly Android Studio. I bought a template for a Logo Quiz game and i managed to make it run without errors and publish it in Play Store as my first game. The player can see a part of the logo and guess the brand name using the given letters
But i would like to use the same template with new graphics and create a music quiz.
Instead of the logo guess game, the player will be able to listen a part of a song and guess the song's title.
The current project is getting the file names from a database stored in assets/databases folder.
So i managed to add start, pause and stop buttons in my activity_play.xml and succesfully created a mediaplayer in activityPlay.java file like:
public void music(View view) {
switch (view.getId()){
case R.id.button:
// Check if mediaPlayer is null. If true, we'll instantiate the MediaPlayer object
if(mediaPlayer == null){
mediaPlayer = MediaPlayer.create(this, R.raw.music);
}
// Then, register OnCompletionListener that calls a user supplied callback method onCompletion() when
// looping mode was set to false to indicate playback is completed.
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
// Here, call a method to release the MediaPlayer object and to set it to null.
stopMusic();
}
});
// Next, call start() method on mediaPlayer to start playing the music.
mediaPlayer.start();
break;
case R.id.button2:
if(mediaPlayer != null) {
// Here, call pause() method on mediaPlayer to pause the music.
mediaPlayer.pause();
}
break;
case R.id.button3:
if(mediaPlayer != null){
// Here, call stop() method on mediaPlayer to stop the music.
mediaPlayer.stop();
// Call stopMusic() method
stopMusic();
}
break;
}
}
private void stopMusic() {
mediaPlayer.release();
mediaPlayer = null;
}
// Call stopMusic() in onStop() overridden method as well.
#Override
protected void onStop() {
super.onStop();
stopMusic();
}
The above code can succesfully play the music.mp3 file located in raw folder. The app i bought is using the following code to load the images and display them for each level:
String image_a = listDataBase.get(1);
String image_q = listDataBase.get(2);
if (isTrue == 1) {
String imgPath;
if (numImage == 0) {
imgPath = "file:///android_asset/logos/" + image_a;
} else {
imgPath = "file:///android_asset/logos/" + image_q;
}
Picasso.get().load(imgPath).into(imageView);
linearLayoutNullClick.setVisibility(View.VISIBLE);
recyclerViewKeys.setVisibility(View.GONE);
trueLogo = 2;
} else {
String imgPath = "file:///android_asset/logos/" + image_q;
Picasso.get().load(imgPath).into(imageView);
recyclerViewKeys.setVisibility(View.VISIBLE);
recyclerViewLogoKeys.setVisibility(View.VISIBLE);
}
So is it possible to use the same code and load the imgPath into mediaPlayer = MediaPlayer.create(this, R.raw.music);
I tried loading imgPath directly to mediaplayer like this but didn't work:
mediaPlayer = MediaPlayer.create(this, imgPath);
Then i tried:
private String audioPath;
audioPath = imgPath;
mediaPlayer = MediaPlayer.create(this, audioPath);
but also didn't work.
Tried many more methods i found on the web, but always i am missing something
As i said before i am a newbie in coding and programming so the solution probably will be very easy .
Anyone can help please?
Are you sure you are getting a audio path in your imgPath object?
Then you can try getting actual storage path from device using code mentioned
here
If you change the value in the database of pic_1.png with audio_1.mp3
then path will start like:
"file:///android_asset/logos/" + YOUR_AUDIO;
So are you sure audio exists in this path?

Preload MediaPlayer in RecyclerView Adapter?

I have an RecylcerView with multiple imges in my app.
If the images are getting loaded in the onBindViewholder it should also prepare the MediaPlayer.
When the user clicks the button it should start the MediaPlayer.
Normaly I would just create the MediaPlayer when the user clicks the button but in my case I'm playing the sound from an URL so it takes some time for the sound to play when the user has bad internet.
So I try to create and prepare the MediaPlayer as soon as the RecyclerView Item gets created and start it when the user clicks the button.
Is this the right way to do it? Because now I have the problem that I have multiple MediaPlayers at once and I don't know how I can stop and clear all MediaPlayers when the user clicks a "stop" button.
Here is the onBindViewHolder method from my RecyclerView Adapter:
#Override
public void onBindViewHolder(#NonNull final SoundViewHolder holder, int position) {
SoundItems currentItem = mSoundItems.get(position);
final String imageUrl = currentItem.getImageResource();
final String mp3Path = currentItem.getMp3Path();
Glide.with(mContext)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(holder.itemImageView);
final MediaPlayer mediaPlayer;
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(mp3Path);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
holder.itemImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mediaPlayer.start();
}
});
What is the best way to preload the sounds so that the sound gets played instantly when the user clicks button and how to stop all MediaPlayers at once?
P.S
The sounds are between 3 and 30 seconds long.
You can use my code :
Instead of using Exoplayer you can use MediaPlayer if you want..
But with this code files will be prefetched too.
https://github.com/NehaKushwah993/InstagramVideoFeedClone
Let me know if it works.

Android mediaplayer won't start after pause

I'm trying make a simple mediaplayer but the pause button doesn't work. When I click on the pause button it stops but when I click on play again it starts at the start again.
I don't know how to make one button where I can play/pause the button.
Code I currently have:
http://pastebin.com/wiDkzw5S
Thanks already!
You would need to save current position of media player and restart it later from that position using seekTo.
Something like:
int currentPos = 0;
pause.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
currentPos = mediaPlayer.getCurrentPosition();
mediaPlayer.pause();
//change image to play
} else {
mediaPlayer.seekTo(currentPos);
mediaPlayer.start();
//again revert image to pause
}
}
});
Hope it helps.
This is running test and running code, you may use this for pause and resume the media player.
int length=0;
Button pause = (Button) findViewById(R.id.pause);
pause.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
length=mediaPlayer.getCurrentPosition();
} else {
mediaPlayer.seekTo(length);
mediaPlayer.start();
}
}
});
I had a similar problem, but I couldn't get it to resume using the methods above.
I discovered my pauseAllSounds() function was pausing all MediaPlayer instances in my sound pool even if they weren't already playing. When that happened, it caused an error in each instance which wasn't playing which prevented that instance from playing again later. I discovered this after some time only by happening across the console output for my running process searching for the cause. It showed line after line of errors, revealing I was trying to pause from an invalid state.
// Make sure you test isPlaying() before pausing
public void pause() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
position = mediaPlayer.getCurrentPosition();
}
}
Once I added the test to only pause if it was already playing, everything worked.

Check and see if a sound is playing, wait for it to finish and then play another

What i am trying to acomplish is for me to click on a button and then play a sound based on a substring.
This is my current code for pressing the button :
display.setText("start");
thefull = thef.getText().toString();
for(int a=0;a<thefull.length();a++)
{
letter=thefull.substring(a,a+1);
if(letter=="m")
{
oursong = MediaPlayer.create(MainActivity.this, R.raw.m);
oursong.start();
while(oursong.isPlaying())
{
display.setText("start");
}
oursong.release();
}
else if(letter=="a")
{
oursong = MediaPlayer.create(MainActivity.this, R.raw.a);
oursong.start();
while(oursong.isPlaying())
{
display.setText("start");
}
oursong.release();
}
display.setText("done");
but for some reason when i click my button no sound is played.
I am also new to android and java programming, so am i going right about doing this?
Because what i really want is for the program to keep checking if a sound is playing(in this case "oursound) when the button is clicked and if the sound is playing i want the program to wait for it to finish to start another sound right after it.
But for now my code doesn´t play any sounds
First of all you need to stop the media player before releasing it(its safer.)
Second, instead of using while(oursong.isPlaying())
{
display.setText("start");
} ; you have to register OnCompletionListener using setOnCompletionListener method. When the song is played endCompletion will be called. Like so;
MediaPlayer mp = new MediaPlayer();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer player) {
player.release();
}});
and inside the onComplete should reset the text "done"

Android: How to stop this music already?

I have created an application and with some background music.
Result = SUCCESS
Problem is.. -.- if app receives a call, music is still playing and plays instead of the user's original ringtone.
Plus if "Home" button is selected on the phone. Activity exits but the music is still running?
I managed to quit the music if the "Back" button on the phone is selected.
other than that music runs 24/7.
What I have used is.
A menu option in the application that when the user selected "Menu" a list of options pop up and an option to choose "Settings..."
If the user selects "Settings..." a preference dialogue pops up to check or uncheck music (ON/OFF)
Result = SUCCESS
The music plays throughout the application, from activity to activity.
This is my media player code in my application.
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
Music.play(this, R.raw.bgmusic);
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(true);
finish();
Music.stop(this);
return true;
}
return super.onKeyDown(keyCode, event);
}
This is my music.java
public class Music {
private static MediaPlayer mp = null;
/** Stop old song and start new one */
public static void play(Context context, int resource) {
stop(context);
// Start music only if not disabled in preferences
if (Prefs.getMusic(context)) {
mp = MediaPlayer.create(context, resource);
mp.setLooping(true);
mp.start();
}
}
/** Stop the music */
public static void stop(Context context) {
if (mp != null) {
mp.stop();
mp.pause();
mp.release();
mp = null;
}
}
}
anyone have a clue?
You need to call
Music.stop(this);
in the onPause method. This may have the effect of an instant glitch, when switching from one of yours activities to another.
Read also this question and the accepted answer.

Categories