I'm writing an Android alarm app. I can get the activity to come up all right when the alarm is triggered (it wakes the phone up, turns off the keyguard and shows the alarm view), but I can't for the life of me get the alarm to sound if the device is in sleep mode when the alarm goes off. (It does sound perfectly when the device is awake and the keyguard is on.) I am using a wake lock. I've tried using the MediaPlayer and the SoundPool with no success. Is there some kind of permission that I'm missing? (I already have WAKE_LOCK, DISABLE_KEYGUARD, and RECEIVE_BOOT_COMPLETED permissions.)
When debugging using the SoundPool I perform the load which returns a valid sound ID integer (1), but the onLoadComplete listener (this is where the sound gets played) is never fired. It fires just fine when the device is awake.
Anyone out there have any ideas or have run into the same problem?
Found the solution! I had the call to play the audio in the onCreate() method of the class. I moved it to onResume() as this is when you know the device is fully awake and the activity is visible, on top and in focus.
I recently encountered the same problem. The way I solved this was reading your answer, but also checking the activity flow by logging what was happening. Basically onCreate, onStart, onResume, onPause, onStop, onStart, onResume was being fired in that order. This was an activity that was started as an alarm screen.
I kept the initialization code in the onStart method, making sure to use .prepare() instead of prepareAsync() since I'm using local sounds.
try {
Log.d(LOG_TAG, "Setting media player URI: " + alarmTone.toString());
//mMediaPlayer = MediaPlayer.create(this, );
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(getApplicationContext(), alarmTone);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mMediaPlayer.setLooping(true);
mMediaPlayer.setVolume(100, 100);
mMediaPlayer.prepare();
} catch (Exception ex) {
Log.d(LOG_TAG, "Exception from media player: " + ex.getMessage());
}
Then inside the onPause and onStop methods, I added:
if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
}
Inside the onResume method I added the media playing code:
if (mMediaPlayer != null && !mMediaPlayer.isPlaying()) {
Log.d(LOG_TAG, "Playing alarm through Media Player");
mMediaPlayer.start();
}
Huzzah, it works!
Related
I'm currently building a streaming Android app and I'm trying to integrate a remote control client (to have for example a control from the lock screen on ICS+).
To do so, I'm doing that at start up in my streaming service:
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
stopSelf();
}
mediaButtonReceiverComponent = new ComponentName(this, RemoteControlReceiver.class);
audioManager.registerMediaButtonEventReceiver(mediaButtonReceiverComponent);
if (remoteControlClientCompat == null) {
final Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.setComponent(mediaButtonReceiverComponent);
remoteControlClientCompat = new RemoteControlClientCompat(
PendingIntent.getBroadcast(
getApplicationContext(),
0,
mediaButtonIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
);
RemoteControlHelper.registerRemoteControlClient(audioManager, remoteControlClientCompat);
}
final int flags = RemoteControlClient.FLAG_KEY_MEDIA_STOP;
remoteControlClientCompat.setTransportControlFlags(flags);
remoteControlClientCompat is simply an instance of RemoteControlClientCompat from the samples.
then during the streaming I'm updating the metadata. everything is working normally, even the controls get sent to my RemoteControlReceiver. The data and the image appear nicely on the lock screen.
Stopping the streaming from my app destroys the lock screen thing but when I'm trying to destroy it from the widget itself (by pressing the stop button), it's doing something weird. Pressing the stop button makes the broadcast receiver stop my streaming service. Then in the service's onDestroy() method, I'm doing that:
RemoteControlHelper.unregisterRemoteControlClient(audioManager, remoteControlClientCompat);
audioManager.unregisterMediaButtonEventReceiver(mediaButtonReceiverComponent);
audioManager.abandonAudioFocus(this);
The widget goes blinking as soon as audioManager.unregisterMediaButtonEventReceiver(mediaButtonReceiverComponent); is called. I've tried commenting the line and the blinking happens with audioManager.abandonAudioFocus(this);. Commenting that other line makes it blink as well when the service stops.
I've noticed this happens too when I'm stopping the streaming from my notification.
What am I doing wrong? I tried changing the order of this calls but I couldn't solve it.
I've notice Spotify had the exact same issue a couple of versions ago. I'm wondering how they solved it...
Ok I fixed it. It's simply because the RemoteControlClient cannot be playing when we abandon audio focus. So I just had to call that before destroying anything:
remoteControlClientCompat.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED);
Hi I need to stop sound from mediaplayer on screen Lock As I am using
if(mp!= null && mp.isPlaying()){
mp.stop();
}
in onPause() . But there is no result. So, How can I stop my media player sound after screen is locked.
To say exactly, I have 16 mp3 files, which will come in random.if a sound is playing and the screen is locked, present sound is Stopped and next one sound is playing.After screen is unlocked, it will works as proper & when the screen is locked , Again same is repeating on my Android 2.3.6 version mobile. How to overcome this.
Thank you.
I have already faced with similar issue, the following code solved my problem:
#Override
public void onPause()
{
super.onPause();
PowerManager mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (!mPowerManager.isScreenOn())
if (mp!= null && mp.isPlaying())
mp.stop();
}
You would need to handle it via Screen On & Off intents.
See the link below for details:
http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/
I think You need to set up your code to stop sound in receiver of
Screen off
here is more detail about how to deal with screen lock receiver . http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/
I want to detect the stop event of android music player.
I am actually calling a method when the file stops playing.
There is an isPlaying method, but in order to get the stop event, I need to put it inside a while loop which might induce instability?
Is there an elegant way to do this?
This is the code I have:
mp.start(); // mp is the media player object
while (mp.isPlaying() == true) continue;
handler.sendEmptyMessage(0);
Thank you.
MediaPlayer has an OnCompletionListener callback you can register to get notified when playback stops.
How to play an audio during splash screen.
Guidance needed.
My way to do this (no external sound needed, since I put my soundfile in my resources-folder):
In onCreate:
mp = MediaPlayer.create(getBaseContext(), R.raw.sound); /*Gets your
soundfile from res/raw/sound.ogg */
mp.start(); //Starts your sound
//Continue with your run/thread-code here
Remember to have the sound in .ogg-format; it's fully supported in Android.
An important thing below about handling the sound when the Splash Screen activity is stopped:
There are two general ways to manage the Splash Screen (and the sound inside it) when it's stopped:
Destroy the whole activity:
protected void onStop() {
super.onStop();
ur.removeCallbacks(myRunnable); /*If the application is stopped;
remove the callback, so the next time the
application starts it shows the Splash Screen again, and also, so the
thread-code,
don't continue after the application has stopped */
finish();
onDestroy();
}
Or you can just stop the sound in onStop:
protected void onStop() {
super.onStop();
if(mp.isPlaying()){ //Must check if it's playing, otherwise it may be a NPE
mp.pause(); //Pauses the sound
ur.removeCallbacks(myRunnable);
}
}
If you choose the second alternative you also have to start your Callback and MediaPlayer in the onStart-method.
I prefer the first alternative.
You can play audio files using the MediaPlayer class.
Example
MediaPlayer player = new MediaPlayer();
player.setDataSource("/sdcard/audiotrack.mp3");
player.prepare();
player.start();
I'm developing an media player application for Android, for which I need to handle any Alarm notification, and based on that I'll pause my playback. When the Alarm in snoozed or dismissed, I'll then resume the playback.
I googled a lot for the Alarm handling, but what I found was the way to enable Alarm notifications through code, set the intent and then handle it. However, no where could I locate just handling the Alarm notification part. I don't need to set the Alarm on, it could've been set by the user, and I don't need to programmatically. All I need is just handle that notification.
Any ideas on this would be extremely useful?
Thanks,
Asheesh
HI Asheesh Vashishtha,
Correct me on this, but AFAIK whenever any other application even if it is the alarm clock, is activated, your activity will surely go in background. So i guess u can override the OnPause and OnResume functions to put your bit of code. As far as snooze or other things are concerned, they all will result in the Alarm Activity getting destroyed(or paused, don know much about it) and your activity will get resumed. So that wont be a matter of concern for u!
Hope this helps...
AFAIK, there is no way for you to be notified of what the Alarm Clock application does, any more than you get notified about any other third-party alarm clock.
Note that AlarmManager -- what you were probably reading about -- is not the same as the Alarm Clock application.
Sorry!
I ran into a similar situation while developing a media player. My solution was to use the AudioManager's OnAudioFocusChangeListener.
You implement the listener in the class like so
public class VideoPlayerHelper implements AudioManager.OnAudioFocusChangeListener {
Then you override onAudioFocusChange
#Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
//Just fall through by omitting break
case AudioManager.AUDIOFOCUS_LOSS:
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
LogUtil.log(LogUtil.DEBUG, TAG, "AUDIOFOCUS_LOSS or AUDIOFOCUS_LOSS_TRANSIENT"); //Custom logging class
if (isPlaying()) {
pause();
mAudioManager.abandonAudioFocus(VideoPlayerHelper.this);
}
break;
case AudioManager.AUDIOFOCUS_GAIN:
LogUtil.log(LogUtil.DEBUG, TAG, "AUDIOFOCUS_GAIN"); //Custom logging class
break;
default:
break;
}
}
The key here is AudioManager.AUDIOFOCUS_LOSS_TRANSIENT. This was the code the listener kept receiving when the alarm clock would go off (on The Note 5). So I simply handled AudioManager.AUDIOFOCUS_LOSS_TRANSIENT the same as AudioManager.AUDIOFOCUS_LOSS by pausing the media player and letting go of the audio focus.
When we setup the media player, I added this line before adding the data source
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
Make sure your code for starting the media player also has this line in it (I have it in the start code and onResume code in case the alarm went off while the app was in the background).
mAudioManager.requestAudioFocus(VideoPlayerHelper.this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
That line helps you get back the audio focus when you hit the play button after dismissing the alarm clock.
You should also let go off audio focus when you're finished with the media player. I put this line of code in the onStop and onDetach methods.
mAudioManager.abandonAudioFocus(VideoPlayerHelper.this);
It's not as much setup as you may think and it allows you to adjust your media player whenever unexpected audio is introduced (such as an alarm clock or timer goes off).