Implemented audiofocuschange listener

This commit is contained in:
daniel oeh 2012-06-15 13:03:55 +02:00
parent b24daa707f
commit a6df2fa2e4
1 changed files with 93 additions and 46 deletions

View File

@ -7,9 +7,12 @@ import android.R;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.media.MediaPlayer;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
@ -32,13 +35,12 @@ public class PlaybackService extends Service {
/** Contains the id of the Feed object of the FeedMedia. */
public static final String EXTRA_FEED_ID = "extra.de.podfetcher.service.feedId";
public static final String ACTION_PLAYER_STATUS_CHANGED =
"action.de.podfetcher.service.playerStatusChanged";
public static final String ACTION_PLAYER_STATUS_CHANGED = "action.de.podfetcher.service.playerStatusChanged";
private static final int NOTIFICATION_ID = 1;
private NotificationCompat.Builder notificationBuilder;
private Notification notification;
private AudioManager audioManager;
private MediaPlayer player;
private FeedMedia media;
private Feed feed;
@ -47,13 +49,13 @@ public class PlaybackService extends Service {
private PositionSaver positionSaver;
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public PlaybackService getService() {
return PlaybackService.this;
}
}
public PlaybackService getService() {
return PlaybackService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
@ -67,6 +69,35 @@ public class PlaybackService extends Service {
return mBinder;
}
private void setupAudioManager() {
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
private final OnAudioFocusChangeListener audioFocusChangeListener = new OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_LOSS:
Log.d(TAG, "Lost audio focus");
pause();
stopSelf();
break;
case AudioManager.AUDIOFOCUS_GAIN:
Log.d(TAG, "Gained audio focus");
play();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
Log.d(TAG, "Lost audio focus temporarily. Ducking...");
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, 0);
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
Log.d(TAG, "Lost audio focus temporarily. Pausing...");
pause();
}
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
long mediaId = intent.getLongExtra(EXTRA_MEDIA_ID, -1);
@ -74,6 +105,10 @@ public class PlaybackService extends Service {
if (mediaId == -1 || feedId == -1) {
Log.e(TAG, "Media ID or Feed ID wasn't provided to the Service.");
} else {
// Intent values appear to be valid
if (audioManager == null) {
setupAudioManager();
}
Feed newFeed = manager.getFeed(feedId);
FeedMedia newMedia = manager.getFeedMedia(mediaId, newFeed);
if (media != null && media != newMedia) {
@ -93,21 +128,22 @@ public class PlaybackService extends Service {
}
media = newMedia;
feed = newFeed;
} else if (media == null) {
media = newMedia;
feed = newFeed;
player = MediaPlayer.create(this, Uri.fromFile(new File(media.getFile_url())));
player = MediaPlayer.create(this,
Uri.fromFile(new File(media.getFile_url())));
setStatus(PlayerStatus.PREPARING);
player.setOnPreparedListener(preparedListener);
Log.d(TAG, "Preparing to play file");
}
}
setupNotification();
return Service.START_STICKY;
}
private void setupPositionSaver() {
if (positionSaver == null) {
positionSaver = new PositionSaver() {
@ -121,7 +157,7 @@ public class PlaybackService extends Service {
protected void onPostExecute(Void result) {
super.onPostExecute(result);
positionSaver = null;
}
}
};
positionSaver.execute();
}
@ -132,10 +168,18 @@ public class PlaybackService extends Service {
public void onPrepared(MediaPlayer mp) {
Log.d(TAG, "Resource prepared");
setStatus(PlayerStatus.PREPARED);
play();
int focusGained = audioManager.requestAudioFocus(
audioFocusChangeListener, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (focusGained == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Log.d(TAG, "Audiofocus successfully requested");
play();
} else {
Log.d(TAG, "Failed to request Audiofocus");
}
}
};
public void pause() {
if (player.isPlaying()) {
Log.d(TAG, "Pausing playback.");
@ -144,7 +188,7 @@ public class PlaybackService extends Service {
setStatus(PlayerStatus.PAUSED);
}
}
public void play() {
if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED) {
Log.d(TAG, "Resuming/Starting playback");
@ -153,83 +197,86 @@ public class PlaybackService extends Service {
setStatus(PlayerStatus.PLAYING);
setupPositionSaver();
} else if (status == PlayerStatus.STOPPED) {
}
}
private void setStatus(PlayerStatus newStatus) {
status = newStatus;
sendBroadcast(new Intent(ACTION_PLAYER_STATUS_CHANGED));
}
private void setupNotification() {
PendingIntent pIntent = PendingIntent.getActivity(
this, 0, new Intent(this, MediaplayerActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap icon = BitmapFactory.decodeResource(null, R.drawable.stat_notify_sdcard);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, new Intent(
this, MediaplayerActivity.class),
PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap icon = BitmapFactory.decodeResource(null,
R.drawable.stat_notify_sdcard);
notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle("Mediaplayer Service")
.setContentInfo("Click here for more info")
.setOngoing(true)
.setContentIntent(pIntent)
.setLargeIcon(icon)
.setSmallIcon(R.drawable.stat_notify_sdcard);
.setContentTitle("Mediaplayer Service")
.setContentText("Click here for more info").setOngoing(true)
.setContentIntent(pIntent).setLargeIcon(icon)
.setSmallIcon(R.drawable.stat_notify_sdcard);
startForeground(NOTIFICATION_ID, notificationBuilder.getNotification());
Log.d(TAG, "Notification set up");
}
/** Seek a specific position from the current position
* @param delta offset from current position (positive or negative)
/**
* Seek a specific position from the current position
*
* @param delta
* offset from current position (positive or negative)
* */
public void seekDelta(int delta) {
seek(player.getCurrentPosition() + delta);
}
public void seek(int i) {
Log.d(TAG, "Seeking position " + i);
player.seekTo(i);
saveCurrentPosition();
}
/** Saves the current position of the media file to the DB */
private synchronized void saveCurrentPosition() {
Log.d(TAG, "Saving current position to " + player.getCurrentPosition());
media.setPosition(player.getCurrentPosition());
manager.setFeedMedia(this, media);
}
public PlayerStatus getStatus() {
return status;
}
public FeedMedia getMedia() {
return media;
}
public MediaPlayer getPlayer() {
return player;
}
/** Periodically saves the position of the media file */
class PositionSaver extends AsyncTask<Void, Void, Void> {
private static final int WAITING_INTERVALL = 5000;
@Override
protected Void doInBackground(Void... params) {
while (!isCancelled() && player.isPlaying()) {
try {
Thread.sleep(WAITING_INTERVALL);
} catch (InterruptedException e) {
Log.d(TAG, "Thread was interrupted while waiting. Finishing now...");
Log.d(TAG,
"Thread was interrupted while waiting. Finishing now...");
return null;
}
saveCurrentPosition();
}
return null;
}
}
}