How to play/stop default sound automatically in Android? - android

I want to play and stop the default sound with following rules:
If the sound is not playing, let play it in 10 seconds.
If the sound is playing, let stop it and play at the first position.
Based on these above rules, I design a function as follows:
public MediaPlayer mp =null;
public void playDefaultSound(){
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
mp = MediaPlayer.create(getApplicationContext(), notification);
try {
if (mp.isPlaying()) {
mp.stop();
mp.release();
mp = MediaPlayer.create(getApplicationContext(), notification);
}
mp.start();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
mp.stop();
mp.release();
}
}, 10000);
} catch (Exception e) {
e.printStackTrace();
}
}
But sometime I still listen two sound are playing (in case of the first sound play and I call the playDefaultSound() function again). Do you think is it correct to delete the mp = MediaPlayer.create(getApplicationContext(), notification); bellow mp.release()? How could I correct the function to satisfy these rules? Thanks all

final MediaPlayer mp = new MediaPlayer();
public void playDefaultSound(){
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
try {
if (mp != null && mp.isPlaying()) {
mp.seekTo(0);
} else {
mp.reset();
mp.setDataSource(getApplicationNotification(), notification);
mp.start();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
mp.stop();
mp.release();
}
}, 10000);
} catch (Exception e) {
e.printStackTrace();
}
}
P.S. - Always see the state diagram or lifecycle of things whenever stuck.
Ref : [Android Media Player State Diagram][1]
[1]: https://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram "MediaPlayer State Diagram"

Related

MediaPlayer sound not always playing, not getting granted audio focus

I'm having an issue with some android code to play a sound notification on certain events.
Here's the code:
int result = audioManager.requestAudioFocus(MainRunningService.afChangeListener,AudioManager.STREAM_NOTIFICATION,AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mp = new MediaPlayer();
mp.setDataSource(context, soundToPlay);
mp.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mp.prepare();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mediaPlayer) {
try {
Log.d(LOGTAG, "SoundService MUSIC: MUSIC IS NOW COMPLETE");
mp.release();
mp = null;
Log.d(LOGTAG, "SoundService MUSIC: MUSIC IS NOW COMPLETE - RELEASED");
} catch (Exception e) {
e.printStackTrace();
}
}
});
mp.setLooping(false);
mp.start();
}
else{
Log.w(LOGTAG, "SoundService Audiofocus was not granted");
}
What I'm finding is that sometimes it will play, whereas other times it won't play. When it doesn't play it's hitting the "SoundSerice Audiofocus was not granted" log line. I've looked at the system logs, but can't find anything that says why it's not been granted.
Once this has happened, then every request seems to fail.
Does anyone have any pointers to what I might be doing wrong?
//call the method playAssistClip() on button click or wherever you want.
private MediaPlayer mp;
private void playAssistClip() {
if (workoutReps.equalsIgnoreCase("6x6x6")) {
mp = MediaPlayer.create(ProcessWorkout.this,
R.raw.six_six_six_formated_ogg);
mp.setOnCompletionListener(new OnCompletionListener() {
//do something after the audi ends
mp.reset();
mp.release();
finish();
}
});
mp.start();
//to get the duration of clip
spentTimeOnWorkout = mp.getDuration();
}

How to correctly change MediaPlayer audio stream type?

I have a simple mp service to play, pause, resume audio. All works fine.
But, last night I have decided to add a feature for user to route audio to ear-piece or speaker and have been battling with mp.setAudioStreamType().
Problem is that I can't change it while service connected and mp created. I don't want to terminate service and/or unbind and rebind as it would require a lot of refactoring
How do I supposed to change AudioStreamType while playing an audio?
Here is my code:
Player service:
public class PService extends Service {
private MediaPlayer mp = new MediaPlayer();
public static final String PLAYING_FINISHED_MSG = "1";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
mp.stop();
mp.release();
}
private void playSong(String file) {
try {
mp.reset();
mp.setDataSource(file);
mp.setAudioStreamType(MYAPP.getAudioStreamType());
mp.prepare();
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
Intent i = new Intent();
i.setAction(MDService.PLAYING_FINISHED_MSG);
sendBroadcast(i);
}
});
toggle route button onclick
currentlyPlayingFile = file;
currentlyPlayingPhone = phone;
lastDurationBeforePause = mpInterface.getCurrentPosition();
if(MYAPP.getAudioStreamType() == AudioManager.STREAM_MUSIC)
{
MYAPP.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
recording_player_route_button.setImageResource(R.drawable.route_off);
}
else{
MYAPP.setAudioStreamType(AudioManager.STREAM_MUSIC);
recording_player_route_button.setImageResource(R.drawable.route_on);
}
try {
mpInterface.playFile(file);
player_seekbar.setProgress(0);
player_seekbar.setMax(mpInterface.getDuration());
//seekto last millisecond after switching from/to sepaker
if(seekTo>0)
{
mpInterface.seekTo(seekTo);
}
isPauseButtonPressed = false;
handleSeekBarUpdate.postDelayed(handleSeekBarUpdateJob, 1);
} catch (RemoteException e) {
e.printStackTrace();
}
The MODIFY_AUDIO_SETTINGS permission is needed in the Manifest for this to work.
AudioManager am=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
am.setMode(AudioManager.MODE_NORMAL);
MediaPlayer mp=new MediaPlayer();
Uri ringtoneUri=RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
try
{
mp.setDataSource(getApplicationContext(), ringtoneUri);
mp.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mp.prepare();
mp.start();
}
catch(Exception e)
{
//exception caught in the end zone
}

How to set a timer for MediaPlayer in Android?

I am developing a phone finder application, and i would like to implement the remote ringing function... I already write a code for MediaPlayer, but when I tested it, the alarm is ringing non-stop (maybe the time for the alarm song is too long but i wanna make it rings for a particular period only)... I hope to set a timer for the alarm ringing like let say ringing for 10 seconds, but no idea on how to achieve it... Need help from you guys... thanks...
MediaPlayer mp = new MediaPlayer();
mp = MediaPlayer.create(RingerActivity.this, R.raw.alarm);
try {
mp.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
Toast.makeText(this, e.getMessage() , Toast.LENGTH_SHORT).show(); }
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
You could use a Runnable and a Handler to stop the MediaPlayer after 10 seconds.
Handler h = new Handler();
Runnable stopPlaybackRun = new Runnable() {
public void run(){
mp.stop();
mp.release();
}
};
h.postDelayed(stopPlaybackRun, 10 * 1000);
Android
media player in timer
MediaPlayer buzzer; //Outside the method
public void BuzzerSound(){
buzzer=MediaPlayer.create(MainActivity.this, R.raw.buzzer_sound);
Thread timer= new Thread(){
public void run(){
try{
buzzer.start();
buzzer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
}catch(Exception e){
e.printStackTrace();
}
}
};
timer.start(); }

android mediaplayer - play ringtone one time

I try to play a device ringtone one time with the MediaPlayer class (I have to use MediaPlayer as I use the ringtones together with other audio sources in my app) So i try the following to play a random ringtone yet I cant stop it looping, it keeps playing. Is it possible to play a ringtone only one time with MediaPlayer.
Thanks
try {
RingtoneManager mRing = new RingtoneManager(RingtoneActivity.this);
int mNumberOfRingtones = mRing.getCursor().getCount();
Uri mRingToneUri = mRing.getRingtoneUri((int) (Math.random() * mNumberOfRingtones));
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(RingtoneActivity.this, mRingToneUri);
mMediaPlayer.prepare();
mMediaPlayer.setLooping(false);
mMediaPlayer.start();
} catch (Exception ignore) {
}
UPDATE:
I just have posted a new question related to this one as I was able to find the specific cause of the trouble in my case.
I found simple solution with use events - confirm answer since it solves your problem :)
mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
#Override
public void onSeekComplete(MediaPlayer mediaPlayer) {
mediaPlayer.stop();
}
});
http://developer.android.com/reference/android/media/MediaPlayer.html
Remember about release().
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
Full code it your want to use need set ring tone to something what you would like.
AudioManager audioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
int volume = audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(view.getContext());
Uri notificationSoundUri = Uri.parse(prefs.getString("notification_sound", "DEFAULT_SOUND"));
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(view.getContext(), notificationSoundUri);
} catch (Exception e1) {
e1.printStackTrace();
mediaPlayer.release();
return;
}
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
try {
mediaPlayer.prepare();
} catch (Exception e1) {
e1.printStackTrace();
mediaPlayer.release();
return;
}
mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
#Override
public void onSeekComplete(MediaPlayer mediaPlayer) {
// TODO Auto-generated method stub
mediaPlayer.stop();
mediaPlayer.start();
}
});
mediaPlayer.setVolume(volume, volume);
mediaPlayer.start();
use Notifications
NotificationManager nManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notifBuilder =
new NotificationCompat.Builder(context);
notifBuilder.setSound(sound);
notification = notifBuilder.build();
nManager.notify(SOME_INT_CONSTANT, notification);

Android mediaplayer causing "dead thread" message

I am starting a sound from a background service (IntentService), which is triggered by a system alarm (the thread of the service will most often be dead when the sound ends).
The relevant code is this:
Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if (alert == null)
alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
MediaPlayer mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(this, alert);
final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if (audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION) != 0) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mMediaPlayer.setLooping(false);
mMediaPlayer.prepareAsync();
mMediaPlayer.start();
}
This stuff works fine, but every time the sound is played, I get this in log cat:
WARN/MessageQueue(7508): Handler{482f97e0} sending message to a Handler on a dead thread
I think this could be due to a callback to the background thread when the sound is finished, or my repeated use of a media player before having finalized the previous one. Any ideas?
Very old question, but #Alex' xkcd link convinced to me answer it anyway.
I have a very similar situation, and was able to achieve the desired result by instantiating the MediaPlayer through a Runnable. In my case an IntentService calls an ongoing Service, which is responsible for the media playback. My solution looks as follows (relevant code only):
public class HelperService extends Service {
public void play() {
Thread thread = new Thread(new Runnable() {
public void run() {
soundStart();
}
});
thread.start();
}
private void soundStart() {
try {
AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(R.raw.sound);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
return false;
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// do stuff
}
});
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Categories

Resources