Media Player doesn't play for the second time - java

I use same button for play and pause.It can handle play and pause smoothly.But after the music file end, it can not play it again.When I press it restart the application.I use mp.reset(); mp.release();.It doesn't help me in the case
Java Code:
final MediaPlayer mp1;
mp1 = MediaPlayer.create(convertView.getContext().getApplicationContext(), convertView.getResources().getIdentifier(audiopath, "raw", convertView.getContext().getPackageName()));
mHolder.play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mp1.isPlaying()) {
mp1.pause();
mHolder.play.setImageResource(R.drawable.plays);
} else {
mp1.start();
mHolder.play.setImageResource(R.drawable.pause);
mp1.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.reset();
mp.release();
mHolder.play.setImageResource(R.drawable.plays);
}
});
}
}
});
LogCat:
java.lang.IllegalStateException
at android.media.MediaPlayer.isPlaying(Native Method)
at com.example.package.adapter.AdapterN$3.onClick(AdapterN.java:223)

img ref
Problem
When you call release() of a MediaPlayer, it deallocates all its resources allocated with MediaPlayer.create() previously, hence no longer being accessible. This produces,
java.lang.IllegalStateException
at android.media.MediaPlayer.isPlaying(Native Method)
at com.example.package.adapter.AdapterN$3.onClick(AdapterN.java:223)
Solution
You should remove,
mp.release()
However, you can still use release() but in that case you have to again create MediaPlayer instance using,
mp1 = MediaPlayer.create(convertView.getContext().getApplicationContext(), convertView.getResources().getIdentifier(audiopath, "raw", convertView.getContext().getPackageName()));
in proper place (i.e. before accessing any start, pause, reset etc.).
Suggestions
Always create MediaPlayer instance in onCreate().
Release MediaPlayer
instance in onDestroy() Use in between.
Use start/pause/reset APIs in between create and release.

Its probably because of the "mp.release()":
As you can see in the documentation here, it state that after release(), the object is no longer available.
So, what i would suggest here is you may just remove the "mp.release()" and put it under onDestroy() of your activity.

Related

Playing a sound on android

I have come across another error along my first app journey :) I want to play a sound when the app loads. Which is a .wav file. It lasts 2 seconds long yet it does not play when I run the app on my old Samsung S4. There is no errors within the IDE or anything I can see, I have checked if 'mp' has a value and it does. Looking around on posts most people have the problem that 'mp' is = null. Whereas mine has a value just no sound comes out of the phone... Again, any help is appreciated!
public class OpeningScreen extends Activity {
#Override
// create the screen state
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// connect the xml layout file
setContentView(R.layout.activity_opening_screen);
final MediaPlayer mp = new MediaPlayer();
mp.create(this, R.raw.welcome_message);
mp.start();
// create the on touch listener
ConstraintLayout layout = (ConstraintLayout) findViewById(R.id.opening_layout);
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// change the screen to a new state
Intent intent = new Intent(OpeningScreen.this, GameScreen.class);
// start the new activity
startActivity(intent);
// stop welcome sound (if still playing)
mp.stop();
return true;
}
});
}
}
public static MediaPlayer create(Context context, int resid) is a static method to create a MediaPlayer for a given resource id.
It means that by calling create you are creating a new instance of media player with no reference usage.
Try to change
final MediaPlayer mp = new MediaPlayer();
mp.create(this, R.raw.welcome_message);
to
final MediaPlayer mp = MediaPlayer.create(this, R.raw. welcome_message);
And the player should work.
It's better to register for OnPreapredListener via MediaPlayer.setOnPreaparedListener and after preparation you start your media playback.
http://developer.android.com/guide/topics/media/mediaplayer.html
Why do you use final?
You can play a mp3 with
MediaPlayer mp = MediaPlayer.create(OpeningScreen.this, R.raw.welcome_message);
mp.start();
Also stopping mediaplayer is better if you stop in onDestroy.
public void onDestroy() {
mp.stop();
super.onDestroy();
}

Resume song in Android

I have created a media player . I run the application properly. But I want to resume my song when I restart my activity. Why does my audio restart when I restart my activity?
How can I do this? I don't understand. Can any one help me??
Here is my code.
public class Audio_Activity extends Activity {
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.audio);
init();
mp=MediaPlayer.create(Audio_Activity.this,R.raw.ennamo_yadho);
Log.e("Song is playing","in Mediya Player ");
if(mp!=null) {
length=mp.getCurrentPosition();
Log.e("Current ","Position -> " + length);
if(length > 0){
mp.seekTo(length);
mp.start();
btnChapter.setEnabled(false);
}
}
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.stop();
mp.release();
btnChapter.setEnabled(true);
System.out.println("Music is over and Button is enable !!!!!!");
}
});
}
}
To prevent this you should use a service for playing sounds while your activity goes to background. Refer to the android's documentation about the life-cycle of an activity to see what actually happens: https://developer.android.com/training/basics/activity-lifecycle/index.html
Can you try:
mp.start();
mp.seekTo(length);
Referring to documentation of MediaPlayer:
public void start ()
Starts or resumes playback. If playback had previously been paused, playback will continue from where it was paused. If playback had been stopped, or never started before, playback will start at the beginning.
Save the mp.getCurrentPosition in a persistence of some sort, sharedprefs for instance in onPause, call pause() on the mediaplayer.
In onResume, do mp.start(), mp.seekTo(savedPosition).

Why does MediaPlayer.setLooping() cause an error when using VideoView?

We are trying to use a VideoView to play a video in an Android Activiy.
I've read the MediaPlayer documentation and studied its state diagram.
We get a Media Player error if we call this method:
MediaPlayer.setLooping()
from this listener method:
MediaPlayer.OnPreparedListener.onPrepared()
The error message from LogCat:
error (-38, 0)
Note:
We have tested on two physical devices and this only happens on our Motorola Xoom.
If I comment out this line: mp.setLooping(false); everything works fine on the Xoom.
(see code below)
According to the documentation, setLooping() can be called from the following Media Player states:
Idle
Initialized
Stopped
Prepared
Started
Paused
PlaybackCompleted
Although the documentation also includes this seemingly contradictory statement:
It is a programming error to invoke methods such as getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioStreamType(int), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(int), prepare() or prepareAsync() in the Idle state...
Question 1:
Why can't we call setLooping() from onPrepared()?
Question 2:
Shouldn't the VideoView be handling the preparation of the underlying MediaPlayer?
Question 3:
Shouldn't the MediaPlayer be in its prepared state when onPrepared() is invoked?
Question 4:
How do I resolve the statements in the documentation that seem to contradict each other?
What really confuses me:
The quote above says none of these methods should be called when the MediaPlayer is in its idle state:
getCurrentPosition()
getDuration()
getVideoHeight()
getVideoWidth()
setAudioStreamType(int)
setLooping(boolean)
setVolume(float
float)
pause()
start()
stop()
seekTo(int)
prepare()
prepareAsync()
This statement (along with our error message) makes me think our error occurs because the MediaPlayer has not been successfully prepared.
But, for some reason there is no problem calling setAudioStreamType().
Question 5:
Why is there a problem with setLooping() but not with setAudioStreamType()?
Both methods are in the list of forbidden methods above.
(That said, I would've thought both are valid in the onPrepared() method...)
What am I missing?
Is there a bug with the Motorola Xoom?
I'd be happy to just get an answer to question 1, but I'm really perplexed by all of this.
I'll admit I'm pretty new to Android development...
Our Xoom is running Ice Cream Sandwich 4.0.4.
Here's some sample code:
class VideoActivity {
VideoView mVidView;
#Override
protected void onCreate(Bundle b) {
mVidView = new VideoView(this);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(mWidth, mHeight);
mVidView.setLayoutParams(params);
mVidView.setVideoURI(mUri);
mVidView.setZOrderOnTop(true);
mMediaController = new MediaController(this, true);
mMediaController.setAnchorView(null);
mVidView.setMediaController(mMediaController);
mVidView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
.
.
.
}
});
mVidView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
.
.
.
}
});
mVidView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mDialog.dismiss();
mMediaPlayer = mp;
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setLooping(false);
mp.setScreenOnWhilePlaying(true);
mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
public void onSeekComplete(MediaPlayer mp) {
mp.start();
}
});
if (mTimecode > 0) {
mp.seekTo(mTimecode * ONE_SEC);
} else {
mp.start();
}
mMediaController.show(0);
}
});
LinearLayout ll = (LinearLayout) this.findViewById(R.id.parentpopup);
ll.addView(mVidView);
}
}

MediaPlayer playback not starting when using Service?

I am making an app which streams music. I am using a service to play music from an online mp3 file in the background. But the the service stops at prepareAsync() and never completes the preparation, and thus the music playback does not start. ie. The onPrepared() method is never called. Note: I used the same code in an activity instead of a service and this problem does not occur. What is wrong here? The code:
public class mp3playerservice extends IntentService implements OnPreparedListener {
String track;
String info[];
String name;
MediaPlayer mp;
Bundle extras;
public mp3playerservice() {
super("mp3playerservice");
}
// Will be called asynchronously be Android
#Override
protected void onHandleIntent(Intent intent) {
extras = intent.getExtras();
info=extras.getStringArray("info");
track=info[1];
name=info[0];
mp= new MediaPlayer();
if(mp.isPlaying()){
mp.release();
mp=new MediaPlayer();
}
start1(track);
}
void start1(String a){
try{
mp.setDataSource(a);
mp.setOnPreparedListener(this);
mp.prepareAsync();
}catch(Exception e){
Log.d("error is "+e.toString(),"error came up");
}
}
public void onPrepared(MediaPlayer mp4){
mp.start();
Log.d("in here2","okay");
}
}
It would have been great if you had also posted the logcat being generated. However, since you are subclassing from IntentService, it appears that once your call to prepareAsync() completes, the service stops itself. The reason for that is because at that point you have effectively finished handling the intent. At this point there are several different ways to fix this. The quickest way, but not the best way, is to change your code so that you call prepare() instead of prepareAsync() and then start() the player and comment out the line that registers the onPreparedListener as well. The best way in my opinion would be to subclass directly from Service and override onStartCommand().

MediaPlayer loops when started from onPause()

I want to play a sound when onPause() of my Activity is called. To do so, I use the following code:
#Override
public void onPause()
{
super.onPause();
MediaPlayer player = MediaPlayer.create(this, Settings.System.DEFAULT_RINGTONE_URI);
player.setLooping(false);
player.start();
}
This works fine, but the sound keeps on playing forever. I tried adding an OnCompletionListener, but that didn't help (the Listener is never called).
I know that I'm not calling player.stop() and player.release() anywhere, but I wouldn't even know where to do so.
My question is now: How can I make the sound play only once? Is there a way to wait for the media player to finish before the application goes to the background?
Ok, I found the solution.
The problem was, that I was using Settings.System.DEFAULT_RINGTONE_URI, which apparently never stops playing.
Using Settings.System.DEFAULT_NOTIFICATION_URI instead fixed the issue.
You can try this (if I've understood correctly)
public boolean test=false; // At begin
public void onPause()
{
super.onPause();
if(!test){
MediaPlayer player = MediaPlayer.create(this, Settings.System.DEFAULT_RINGTONE_URI);
player.setLooping(false);
player.start();
test=true;
}
}
Maybe I don't understand what you want to say. If you explain us a little bit more, maybe we can help to you :)
I haven't done this,, but I think you can check this one
player.setLooping(false);
player.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
player.stop();
player.release();
}
});
Not sure why it plays in loop but you can you use MediaElement to play sound? You can identify when media is ended by using method MediaEnded and then call stop method to stop playing audio

Categories

Resources