I am using an Android MediaPlayer to play from a local source. It is working well other than one bug when restarting the sound.
public void create() {
FileInputStream in = mApp.openFileInput(mMusicFile);
mp = new MediaPlayer();
mp.setDataSource(in.getFD());
mp.prepare();
mp.setLooping(true);
}
public void play() {
mp.start();
}
public void stop() {
mp.stop();
mp.prepare();
mp.seekTo(0);
}
If I call stop(), then a second or so later call play() I hear a brief clip of the sound where it had been stopped then it sound restarts.
I believe this is a known bug in Android 2.2 Froyo. The prescribed work around is to delete the MediaPlayer and make a new one or fade in to the playback.
The internal buffers are not being flushed after the seek.
Related
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.
I have 8 audio files that I need to play when a button is pressed.
Currently, these files are played using a class. In this class, each audio file has it's own function that plays and pauses each audio file.
Is there a way to do this without repeating the same function for different audio files?
The button in question is connected to an Adafruit feather - essentially if the button is pressed the phone knows to play whichever audio is required.
Here's some code:
Here's what I have so far:
public class Audio {
MediaPlayer mp;
boolean paused = false;
public void playSound_1(Context context) {
mp = MediaPlayer.create(context, R.raw.Sound_1);
mp.start();
}
public void playSound_2(Context context) {
mp = MediaPlayer.create(context, R.raw.Sound_2);
mp.start();
}
public void playSound_3(Context context) {
mp = MediaPlayer.create(context, R.raw.Sound_3);
mp.start();
}
}
In my fragment I then call the function for each sound:
if (data_check.contains("Sound_1"){
audio.playSound_1(this.getContext());
}
else if (data_check.contains("Sound_2"){
audio.playSound_2(this.getContext());
}
The current results are that if the button is pressed (and data_check finds the name of the Sound) that sound plays.
What I'd like to do is have the same results but without having public void playSound_1, 2, 3, 4... etc.
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();
}
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().
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