How to Play/Stop sound over background music with a switch button - android

I am developing a game on Android, I have a background music that I would like to stop using a switch that is in an activity other than the one where I launch the music, that of the parameters. The music is in the main menu.
Here is my class for the music:
public class BackgroundMusic {
private MediaPlayer player;
public Menu context;
public BackgroundMusic(Menu pContext) {
context = pContext;
player = MediaPlayer.create(context.getApplicationContext(), R.raw.opening);
player.setLooping(true);
player.setVolume(1.0f, 1.0f);
}
public void start() {
player.start();
}
public void stop(){
player.pause();
}
}
And here is the code I use for the switch:
buttonmusique = (Switch) findViewById(R.id.switch3);
buttonmusique.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.e("bouton",String.valueOf(buttonmusique.isChecked()));
// If the music is playing
if (isChecked) {
media.start();
buttonmusique.setText("Musique On"); //To change the text near to switch
Log.d("You are :", "Checked");
} else {
media.stop();
// Resume the music player
buttonmusique.setText("Musique OFF"); //To change the text near to switch
Log.d("You are :", " Not Checked");
}
}
});
The problem is that, if I press the switch, it sends me back to the main menu (on some phones the application crashed).
This is the logcat :
E/bouton: false
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: pts3.botanicagofinal, PID: 14271
java.lang.NullPointerException: Attempt to invoke virtual method 'void pts3.botanicagofinal.BackgroundMusic.stop()' on a null object reference
at pts3.botanicagofinal.Parametres$3.onCheckedChanged(Parametres.java:61)
at android.widget.CompoundButton.setChecked(CompoundButton.java:156)
at android.widget.Switch.setChecked(Switch.java:1071)
at android.widget.Switch.toggle(Switch.java:1066)
at android.widget.CompoundButton.performClick(CompoundButton.java:120)
at android.view.View$PerformClick.run(View.java:22314)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:6223)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Application terminated.
I want to know if it is possible to do otherwise for it to work or if I have an error in my code?
Thank you in advance for your feedback.

Related

CameraX - crash app on onPause() while recording video

if minimize app while recording video - everything all right, but once I deploy the application, ерут getting this error:
E/AndroidRuntime: FATAL EXCEPTION: CameraX-video encoding thread
Process: <pkgname>, PID: 12340
java.lang.IllegalStateException
at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:2698)
at androidx.camera.core.VideoCapture.videoEncode(VideoCapture.java:604)
at androidx.camera.core.VideoCapture$2.run(VideoCapture.java:348)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.os.HandlerThread.run(HandlerThread.java:65)
Or
if I stopped recording on onPause videoCapture?.stopRecording(), then getting this error:
E/AndroidRuntime: FATAL EXCEPTION: CameraX-
Process: <pkgname>, PID: 9489
java.lang.IllegalStateException
at androidx.core.util.Preconditions.checkState(Preconditions.java:96)
at androidx.core.util.Preconditions.checkState(Preconditions.java:108)
at androidx.camera.camera2.impl.Camera.openCaptureSession(Camera.java:874)
at androidx.camera.camera2.impl.Camera.onUseCaseReset(Camera.java:625)
at androidx.camera.camera2.impl.Camera$11.run(Camera.java:611)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.os.HandlerThread.run(HandlerThread.java:65)
How right stop record video while minimize app???
here's my code:
I collect configurations:
CameraX.unbindAll()
getDisplayMetrics()
setPreviewConfig()
when (typeCapture) {
TYPE_IMAGE -> {
setImageCapture()
CameraX.bindToLifecycle(this, preview, imageCapture)
}
TYPE_VIDEO -> {
setVideoCapture()
CameraX.bindToLifecycle(this, preview, videoCapture)
}
}
set videoConfig and videoCapture:
val videoCaptureConfig = VideoCaptureConfig.Builder().apply {
setLensFacing(lensFacing)
setTargetAspectRatioCustom(screenAspectRatio)
setTargetRotation(rotation)
}.build()
videoCapture = VideoCapture(videoCaptureConfig)
then I start recording video:
videoCapture?.startRecording(videoFile,
CameraXExecutors.mainThreadExecutor(), recordListener)
on onPause() the errors I get are described above
Thanks
I had the same error when stoping the video on onPause. To solve it I added a delay before to call super.onPause() ( see : android: camera onPause/onResume issue).
Declare videoSavedListener
private VideoCapture.OnVideoSavedListener videoSavedListener= new VideoCapture.OnVideoSavedListener() {
#Override
public void onVideoSaved(#NonNull File file) {
if(isRecording) {
isRecording = false;
// Do whatever you want
}
}
#Override
public void onError(#NonNull VideoCapture.VideoCaptureError videoCaptureError, #NonNull String message, #Nullable Throwable cause) {
}
};
Add onClickListener
button.setOnClickListener(v -> {
if(!isRecording){
videoCapture.startRecording(videoFile, CameraXExecutors.mainThreadExecutor(), videoSavedListener);
isRecording = true;
}else{
videoCapture.stopRecording();
}
});
Override onPause()
#SuppressLint("RestrictedApi")
#Override
public void onPause() {
if(isRecording){
isRecording = false;
videoCapture.stopRecording();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onPause();
}else
super.onPause();
}
Please note that video recording use case is currently marked as
hidden in the API and is in a very preliminary state and subject to
change.
EDIT: With some devices the app still crash when calling onPause() with the videoCapture use case set. I added CameraX.unbindAll() to remove all the use cases before calling super.onPause(). Then, in the onResume() method I bind them again.
Declare a boolean variable
public class MyClass{
private boolean isSafe;
private boolean isPending
onPause{
isSafe=false;
}
onPostResume{
isSafe=true;
if(isPending)
methodForDoingUrAction();
}
methodForDoingUrAction(){
if(isSAfe){
//do your process
isPending=false;
}
else
isPending=true;
}
}

MediaPlayer.create() returns NULL

I followed a youtube tutorial that showed how to create an android mp3 player app. The App has multiple buttons, one for previous song, one for Pause/Play and one for next song. Play/Pause buttons, only pause my MediaPlayer and they work perfectly no matter how many times i click them.
On the other hand, Next/Previous buttons causes my code to throw NullPointerException. I found out it was because MediaPlayer.create(Context, Uri) function sometimes returns null. On my app, function fails approx. on every tenth press of Next button, or on every tenth creation of MediaPlayer.
Is there a way to fix this? I tried modifying application on my own, but it didn't work. I tried looping variable myMysicPlayer in continue while loop, until it gets while != null
while(myMusicPlayer != null){
Uri u = new Uri(...);
myMediaPlayer = MediaPlayer.create(getAppContext(), u);
}
I tried using a listener that waits till myMusicPlayer was ready to be stopped, but it was just dereferencing null, and that failed obviosely.
btnNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
myMediaPlayer.stop();
myMediaPlayer.reset();
myMediaPlayer.release();
position = (position + 1) % mySongs.size();
Uri u = Uri.parse(mySongs.get(position).toString());
songLabelName.setText(mySongs.get(position).toString());
myMediaPlayer = MediaPlayer.create(getApplicationContext(), u);
myMediaPlayer.start();
}
});
The error message:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.aizenangel.myapplication, PID: 20169
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.start()' on a null object reference at com.aizenangel.myapplication.SongPlayer$4.onClick(SongPlayer.java:168)
at android.view.View.performClick(View.java:6291)
at android.view.View$PerformClick.run(View.java:24931)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
I/Process: Sending signal. PID: 20169 SIG: 9
My mistake was:
1) i used myMediaPlayer.release() method, that releases all resources
associated with the MediaPlayer object
2) instead of using the same MediaPlayer object, i always create new one with myMediaPlayer = MediaPlayer.create(Context, Uri), and
MediaPlayer.create(Context, Uri) returns null on failure, which than causes NullPointerException.
Solution was simple. I deleted myMediaPlayer.release() line and instead of creating new object, i modified the one whose reference i got in the begining.
btnNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
myMediaPlayer.stop();
myMediaPlayer.reset();
position = (position+1)%mySongs.size();
Uri u = Uri.parse((mySongs.get(position)).toString());
songLabelName.setText(mySongs.get(position).toString());
try {
myMediaPlayer.setDataSource(getApplicationContext(),u);
myMediaPlayer.prepare();
}catch (IOException e) {
e.printStackTrace();
}
myMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
myMediaPlayer.start();
}
});
}
});

Android MediaPlayer class throws java.lang.IllegalStateException after activity resumed

I'm trying to pause and resume VideoView with MediaPlayer in activity onPause() and onResume() methods, but in onResume() method MediaPlayer throws java.lang.IllegalStateException. I didn't release MediaPlayer but I think MediaPlayer automatically released after activity paused.
How should I handle it?
private MediaPlayer mediaPlayer;
void prepareVideo() {
videoView = new VideoView(context.getApplicationContext());
String path = "android.resource://" + getPackageName() + "/" +
R.raw.my_video;
videoView.setVideoPath(path);
}
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer = mp;
mediaPlayer.start();
}
});
#Override
protected void onResume() {
super.onResume();
if (mediaPlayer != null) {
mediaPlayer.start();
}
}
#Override
protected void onPause() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
super.onPause();
}
The exception:
Caused by: java.lang.IllegalStateException
at android.media.MediaPlayer._start(Native Method)
at android.media.MediaPlayer.start(MediaPlayer.java:1194)
at co.myapp.app.reborn.myappTestActivity.onResume(myappTestActivity.java:370)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1259)
at android.app.Activity.performResume(Activity.java:6347)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3110)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3152) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1400) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5530) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:734) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624) 
Take a look at the mediaplayer state diagram on android documentation
MediaPlayer state diagram
According to the diagram you have to call setDataSource() and prepare() before calling start().
Probably something wrong happened before. Your logcat should point you in the right direction.
My guess is that your mediaplayer is not in paused state but in stopped state. So you have to call prepare and then start, not just start.
Unfortunately in this way your playback will restart from scratch.
You can use seek command for resuming a position saved during the activity pausing.
We just need to implement MediaPlayer.OnSeekCompleteListener interface and set MediaPlayer in onSeekComplete method.
private MediaPlayer mediaPlayer;
#Override
public void onSeekComplete(final MediaPlayer mp) {
mediaPlayer = mp;
}
I was facing this issue yesterday and I'd like to share my experience facing this issue, the root cause and the fix in my particular issue; this might be helpful for someone else.
This is what I found in my particular issue.
I´m running MediaPlayer in Fragment
When the phone goes to sleep (black screen), in the fragment-life-cycle the stop() function is call.
MediaPlayer recommends to release() MediaPlayer resources on STOP state.
When the phone resumes, it complains with illegal-state-exception because there are no MediaPlayer resource available, remember it was released in the STOPE state.
So, to fix it. I overrided start() state and I got another instance of MediaPlayer if it was null at that specific point in time. START state is called at resume time.
sample code
public class xMediaPlayer extends MediaPlayer
{
private static xMediaPlayer instance = null;
public static xMediaPlayer getInstance( )
{
if( instance == null )
instance = new xMediaPlayer( );
return instance;
}
}
Override start() on fragment
#Override
public void onStart() {
super.onStart();
mMediaPlayer = xMediaPlayer.getInstance( );
}

Android MediaPlayer : IllegalStateException when app closes/press back button

Im streaming an mp3 audio from a url by using mediaplayer, Now im able to play music , But when i press back button or close the app, it crashes.
can anyone pls help me to find my mistake.
thank you.
My code is :
private ImageView play, forward, backward;
private MediaPlayer mediaPlayer;
private boolean playing = false;
private ProgressDialog dialog;
private String mp3link;
private SeekBar seekbar;
private Handler handler = new Handler();
private int mediaPos;
private int mediaMax;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String url ="";
initWidgets();
}
private void initWidgets() {
mp3link = "http://loc8app.com/church/uploads/audio/749928ad6fcb7b1aceefdf03bd7a9465.mp3";
play = (ImageView) findViewById(R.id.control);
seekbar = (SeekBar) findViewById(R.id.seekBar);
// forward = (ImageView) findViewById(R.id.playeer_forward);
// backward = (ImageView) findViewById(R.id.playeer_back);
mediaPlayer = new MediaPlayer();
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
playFunction();
}
});
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(mediaPlayer != null && fromUser){
mediaPlayer.seekTo(progress);
}
}
});
}
private void playFunction() {
if (!playing) {
try {
dialog = ProgressDialog
.show(MainActivity.this,
"",
getString(com.root5solutions.music.R.string.buffering),
true);
dialog.setCancelable(true);
dialog.show();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(mp3link);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
play.setBackgroundResource(R.drawable.pause);
playing = true;
//this is new
mediaPos = mp.getCurrentPosition();
mediaMax = mp.getDuration();
seekbar.setMax(mediaMax);
seekbar.setProgress(mediaPos);
//this line is the error
handler.removeCallbacks(moveSeekBarThread);
handler.postDelayed(moveSeekBarThread, 100);
mp.start();
dialog.dismiss();
}
});
mediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
dialog.dismiss();
}
} else {
play.setBackgroundResource(R.drawable.play);
mediaPlayer.stop();
mediaPlayer.release();
playing = false;
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
private Runnable moveSeekBarThread = new Runnable() {
public void run() {
if (mediaPlayer.isPlaying()) {
int mediaPos_new = mediaPlayer.getCurrentPosition();
int mediaMax_new = mediaPlayer.getDuration();
seekbar.setMax(mediaMax_new);
seekbar.setProgress(mediaPos_new);
handler.postDelayed(this, 1000); // Looping the thread after 1 second
}
}
};
}
Logcat shows :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.root.music, PID: 26981
java.lang.IllegalStateException
at android.media.MediaPlayer.isPlaying(Native Method)
at com.root.music.MainActivity$4.run(MainActivity.java:132)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5351)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:947)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:742)
The issue appears to be being caused by the moveSeekBarThread Runnable, from which the exception is being raised, continuing to execute after mediaPlayer is released in onBackPressed(). This results in the the isPlaying() method being executed, which as per the documentation will result in an IllegalStateException:
if the internal player engine has not been initialized or has been released.
Looking at moveSeekBarThread, it seems to be configured to reschedule itself endlessly by posting itself back into the handler Handler instance with a delay. This process is not being stopped when the user leaves the activity, which explains why moveSeekBarThread keeps running. So, based on the above, one solution could be to make sure that any instances of moveSeekBarThread in handler's queue are removed before calling mediaPlayer.release() when the user leaves the activity.
You should be able to do that by calling handler.removeCallbacks(moveSeekBarThread); before you call mediaPlayer.release(). For example, as follows:
#Override
public void onBackPressed() {
super.onBackPressed();
handler.removeCallbacks(moveSeekBarThread);
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
It should be okay to call it right before mediaPlayer.release(), but I think it's safer to call it regardless of whether mediaPlayer is playing. This way, if the Runnable does get or remain started somehow despite the media player not having being started or having been stopped, the Runnable will still be cleared.
As an aside, while I don't have any experience with MediaPlayer, I happened to notice that the documentation of the release method has the following to say:
It is considered good practice to call this method when you're done using the MediaPlayer. In particular, whenever an Activity of an application is paused (its onPause() method is called), or stopped (its onStop() method is called), this method should be invoked to release the MediaPlayer object, unless the application has a special need to keep the object around. In addition to unnecessary resources (such as memory and instances of codecs) being held, failure to call this method immediately if a MediaPlayer object is no longer needed may also lead to continuous battery consumption for mobile devices, and playback failure for other applications if no multiple instances of the same codec are supported on a device.
So unless there is that special need to keep the media player around in the activity in your case, it might be better to handle the release process (including clearing moveSeekBarThread from handler) in onPause or onStop instead.
Hope that helps!
you are getting IllegalStateException .
Signals that a method has been invoked at an illegal or inappropriate
time .
Call super.onBackPressed(); after if condition
#Override
public void onBackPressed()
{
if (mediaPlayer!= null)
{
if(mediaPlayer.isPlaying())
mediaPlayer.stop();
mediaPlayer.release();
}
super.onBackPressed(); // Call here
}
First you need to understand what illegalStateException means:
According to Android docs:
It Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.
have a look at the state diagram of a media player:
https://developer.android.com/images/mediaplayer_state_diagram.gif
Calling setDataSource(FileDescriptor), or setDataSource(String), or setDataSource(Context, Uri), or setDataSource(FileDescriptor, long, long), or setDataSource(MediaDataSource) transfers a MediaPlayer object in the Idle state to the Initialized state.
An IllegalStateException is thrown if setDataSource() is called in any other state.
It is good programming practice to always look out for IllegalArgumentException and IOException that may be thrown from the overloaded setDataSource methods.

IllegalStateException occurs in mediaPlayer when start online streaming second time

I am creating a simple online audio streaming app.It has 4 buttons Play,Stop,Resume,Pause.When i press stop button,it works fine after that when i start again,application crashes.It gives the following exception
java.lang.IllegalStateException
at android.media.MediaPlayer._setAudioStreamType(Native Method)
at android.media.MediaPlayer.setAudioStreamType(MediaPlayer.java:1723)
at com.onlinestreaming.MediaPlayerActivity.onClick(MediaPlayerActivity.java:48)
at android.view.View.performClick(View.java:5204)
at android.view.View$PerformClick.run(View.java:21153)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
this is what i have done
#Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.play:
pd = new ProgressDialog(this);
pd.setMessage("Buffering");
pd.show();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setOnPreparedListener(this);
mp.setOnErrorListener(this);
try {
// mp.setDataSource("http://www.robtowns.com/music/blind_willie.mp3");
//mp.setDataSource("http://picosong.com/zkWc");
mp.setDataSource("http://songs1.djmazadownload.com/music/indian_movies/Banjo%20%282016%29/01%20-%20Bappa%20-%20Banjo%20%5BDJMaza.Cool%5D.mp3");
} catch (IOException e) {
Toast.makeText(this, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
mp.prepareAsync();
mp.setOnCompletionListener(this);
break;
case R.id.Stop:
mp.stop();
mp.reset();
mp.release();
break;
case R.id.Resume:
mp.start();
break;
case R.id.Pause:
Toast.makeText(this, "Hit", Toast.LENGTH_SHORT).show();
if (mp.isPlaying()) {
mp.pause();
} else {
mp.start();
}
// mp.pause();
break;
}
}
#Override
public void onCompletion(MediaPlayer mp) {
pd.dismiss();
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
pd.dismiss();
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
Toast.makeText(this, "Prepared Finished", Toast.LENGTH_SHORT).show();
pd.setMessage("Playing.......");
mp.start();
}
On stop button press, you are releasing the resource of the MediaPlayer object.
release():
Releases resources associated with this MediaPlayer object. It is
considered good practice to call this method when you're done using
the MediaPlayer. In particular, whenever an Activity of an application
is paused (its onPause() method is called), or stopped (its onStop()
method is called), this method should be invoked to release the
MediaPlayer object, unless the application has a special need to keep
the object around. In addition to unnecessary resources (such as
memory and instances of codecs) being held, failure to call this
method immediately if a MediaPlayer object is no longer needed may
also lead to continuous battery consumption for mobile devices, and
playback failure for other applications if no multiple instances of
the same codec are supported on a device. Even if multiple instances
of the same codec are supported, some performance degradation may be
expected when unnecessary multiple instances are used at the same
time.
So remove mp.release() from stop button clicklistener.
case R.id.Stop:
mp.stop();
mp.reset();
break;
You call mp.release() if the user clicks STOP. This will put the MediaPlayer in the 'End' state (see this state diagram).
So if the user clicks START the next time, you have to use a new MediaPlayer instance because setAudioStreamType() may only be used in the following states (see the MediaPlayer documentation):
Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted

Categories

Resources