Implemented audiofocuschange listener
This commit is contained in:
parent
b24daa707f
commit
a6df2fa2e4
@ -7,9 +7,12 @@ import android.R;
|
|||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.media.AudioManager.OnAudioFocusChangeListener;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -32,13 +35,12 @@ public class PlaybackService extends Service {
|
|||||||
/** Contains the id of the Feed object of the FeedMedia. */
|
/** 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 EXTRA_FEED_ID = "extra.de.podfetcher.service.feedId";
|
||||||
|
|
||||||
public static final String ACTION_PLAYER_STATUS_CHANGED =
|
public static final String ACTION_PLAYER_STATUS_CHANGED = "action.de.podfetcher.service.playerStatusChanged";
|
||||||
"action.de.podfetcher.service.playerStatusChanged";
|
|
||||||
|
|
||||||
private static final int NOTIFICATION_ID = 1;
|
private static final int NOTIFICATION_ID = 1;
|
||||||
private NotificationCompat.Builder notificationBuilder;
|
private NotificationCompat.Builder notificationBuilder;
|
||||||
|
|
||||||
private Notification notification;
|
private AudioManager audioManager;
|
||||||
private MediaPlayer player;
|
private MediaPlayer player;
|
||||||
private FeedMedia media;
|
private FeedMedia media;
|
||||||
private Feed feed;
|
private Feed feed;
|
||||||
@ -47,13 +49,13 @@ public class PlaybackService extends Service {
|
|||||||
private PositionSaver positionSaver;
|
private PositionSaver positionSaver;
|
||||||
|
|
||||||
private final IBinder mBinder = new LocalBinder();
|
private final IBinder mBinder = new LocalBinder();
|
||||||
|
|
||||||
public class LocalBinder extends Binder {
|
public class LocalBinder extends Binder {
|
||||||
public PlaybackService getService() {
|
public PlaybackService getService() {
|
||||||
return PlaybackService.this;
|
return PlaybackService.this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
@ -67,6 +69,35 @@ public class PlaybackService extends Service {
|
|||||||
return mBinder;
|
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
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
long mediaId = intent.getLongExtra(EXTRA_MEDIA_ID, -1);
|
long mediaId = intent.getLongExtra(EXTRA_MEDIA_ID, -1);
|
||||||
@ -74,6 +105,10 @@ public class PlaybackService extends Service {
|
|||||||
if (mediaId == -1 || feedId == -1) {
|
if (mediaId == -1 || feedId == -1) {
|
||||||
Log.e(TAG, "Media ID or Feed ID wasn't provided to the Service.");
|
Log.e(TAG, "Media ID or Feed ID wasn't provided to the Service.");
|
||||||
} else {
|
} else {
|
||||||
|
// Intent values appear to be valid
|
||||||
|
if (audioManager == null) {
|
||||||
|
setupAudioManager();
|
||||||
|
}
|
||||||
Feed newFeed = manager.getFeed(feedId);
|
Feed newFeed = manager.getFeed(feedId);
|
||||||
FeedMedia newMedia = manager.getFeedMedia(mediaId, newFeed);
|
FeedMedia newMedia = manager.getFeedMedia(mediaId, newFeed);
|
||||||
if (media != null && media != newMedia) {
|
if (media != null && media != newMedia) {
|
||||||
@ -93,21 +128,22 @@ public class PlaybackService extends Service {
|
|||||||
}
|
}
|
||||||
media = newMedia;
|
media = newMedia;
|
||||||
feed = newFeed;
|
feed = newFeed;
|
||||||
|
|
||||||
} else if (media == null) {
|
} else if (media == null) {
|
||||||
media = newMedia;
|
media = newMedia;
|
||||||
feed = newFeed;
|
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);
|
setStatus(PlayerStatus.PREPARING);
|
||||||
player.setOnPreparedListener(preparedListener);
|
player.setOnPreparedListener(preparedListener);
|
||||||
Log.d(TAG, "Preparing to play file");
|
Log.d(TAG, "Preparing to play file");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
setupNotification();
|
setupNotification();
|
||||||
return Service.START_STICKY;
|
return Service.START_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupPositionSaver() {
|
private void setupPositionSaver() {
|
||||||
if (positionSaver == null) {
|
if (positionSaver == null) {
|
||||||
positionSaver = new PositionSaver() {
|
positionSaver = new PositionSaver() {
|
||||||
@ -121,7 +157,7 @@ public class PlaybackService extends Service {
|
|||||||
protected void onPostExecute(Void result) {
|
protected void onPostExecute(Void result) {
|
||||||
super.onPostExecute(result);
|
super.onPostExecute(result);
|
||||||
positionSaver = null;
|
positionSaver = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
positionSaver.execute();
|
positionSaver.execute();
|
||||||
}
|
}
|
||||||
@ -132,10 +168,18 @@ public class PlaybackService extends Service {
|
|||||||
public void onPrepared(MediaPlayer mp) {
|
public void onPrepared(MediaPlayer mp) {
|
||||||
Log.d(TAG, "Resource prepared");
|
Log.d(TAG, "Resource prepared");
|
||||||
setStatus(PlayerStatus.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() {
|
public void pause() {
|
||||||
if (player.isPlaying()) {
|
if (player.isPlaying()) {
|
||||||
Log.d(TAG, "Pausing playback.");
|
Log.d(TAG, "Pausing playback.");
|
||||||
@ -144,7 +188,7 @@ public class PlaybackService extends Service {
|
|||||||
setStatus(PlayerStatus.PAUSED);
|
setStatus(PlayerStatus.PAUSED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void play() {
|
public void play() {
|
||||||
if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED) {
|
if (status == PlayerStatus.PAUSED || status == PlayerStatus.PREPARED) {
|
||||||
Log.d(TAG, "Resuming/Starting playback");
|
Log.d(TAG, "Resuming/Starting playback");
|
||||||
@ -153,83 +197,86 @@ public class PlaybackService extends Service {
|
|||||||
setStatus(PlayerStatus.PLAYING);
|
setStatus(PlayerStatus.PLAYING);
|
||||||
setupPositionSaver();
|
setupPositionSaver();
|
||||||
} else if (status == PlayerStatus.STOPPED) {
|
} else if (status == PlayerStatus.STOPPED) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setStatus(PlayerStatus newStatus) {
|
private void setStatus(PlayerStatus newStatus) {
|
||||||
status = newStatus;
|
status = newStatus;
|
||||||
sendBroadcast(new Intent(ACTION_PLAYER_STATUS_CHANGED));
|
sendBroadcast(new Intent(ACTION_PLAYER_STATUS_CHANGED));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupNotification() {
|
private void setupNotification() {
|
||||||
PendingIntent pIntent = PendingIntent.getActivity(
|
PendingIntent pIntent = PendingIntent.getActivity(this, 0, new Intent(
|
||||||
this, 0, new Intent(this, MediaplayerActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
|
this, MediaplayerActivity.class),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
Bitmap icon = BitmapFactory.decodeResource(null, R.drawable.stat_notify_sdcard);
|
|
||||||
|
Bitmap icon = BitmapFactory.decodeResource(null,
|
||||||
|
R.drawable.stat_notify_sdcard);
|
||||||
notificationBuilder = new NotificationCompat.Builder(this)
|
notificationBuilder = new NotificationCompat.Builder(this)
|
||||||
.setContentTitle("Mediaplayer Service")
|
.setContentTitle("Mediaplayer Service")
|
||||||
.setContentInfo("Click here for more info")
|
.setContentText("Click here for more info").setOngoing(true)
|
||||||
.setOngoing(true)
|
.setContentIntent(pIntent).setLargeIcon(icon)
|
||||||
.setContentIntent(pIntent)
|
.setSmallIcon(R.drawable.stat_notify_sdcard);
|
||||||
.setLargeIcon(icon)
|
|
||||||
.setSmallIcon(R.drawable.stat_notify_sdcard);
|
|
||||||
|
|
||||||
|
|
||||||
startForeground(NOTIFICATION_ID, notificationBuilder.getNotification());
|
startForeground(NOTIFICATION_ID, notificationBuilder.getNotification());
|
||||||
Log.d(TAG, "Notification set up");
|
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) {
|
public void seekDelta(int delta) {
|
||||||
seek(player.getCurrentPosition() + delta);
|
seek(player.getCurrentPosition() + delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void seek(int i) {
|
public void seek(int i) {
|
||||||
Log.d(TAG, "Seeking position " + i);
|
Log.d(TAG, "Seeking position " + i);
|
||||||
player.seekTo(i);
|
player.seekTo(i);
|
||||||
saveCurrentPosition();
|
saveCurrentPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Saves the current position of the media file to the DB */
|
/** Saves the current position of the media file to the DB */
|
||||||
private synchronized void saveCurrentPosition() {
|
private synchronized void saveCurrentPosition() {
|
||||||
Log.d(TAG, "Saving current position to " + player.getCurrentPosition());
|
Log.d(TAG, "Saving current position to " + player.getCurrentPosition());
|
||||||
media.setPosition(player.getCurrentPosition());
|
media.setPosition(player.getCurrentPosition());
|
||||||
manager.setFeedMedia(this, media);
|
manager.setFeedMedia(this, media);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerStatus getStatus() {
|
public PlayerStatus getStatus() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedMedia getMedia() {
|
public FeedMedia getMedia() {
|
||||||
return media;
|
return media;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MediaPlayer getPlayer() {
|
public MediaPlayer getPlayer() {
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Periodically saves the position of the media file */
|
/** Periodically saves the position of the media file */
|
||||||
class PositionSaver extends AsyncTask<Void, Void, Void> {
|
class PositionSaver extends AsyncTask<Void, Void, Void> {
|
||||||
private static final int WAITING_INTERVALL = 5000;
|
private static final int WAITING_INTERVALL = 5000;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... params) {
|
protected Void doInBackground(Void... params) {
|
||||||
while (!isCancelled() && player.isPlaying()) {
|
while (!isCancelled() && player.isPlaying()) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(WAITING_INTERVALL);
|
Thread.sleep(WAITING_INTERVALL);
|
||||||
} catch (InterruptedException e) {
|
} 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;
|
return null;
|
||||||
}
|
}
|
||||||
saveCurrentPosition();
|
saveCurrentPosition();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user