summaryrefslogtreecommitdiff
path: root/core/src/main/java
diff options
context:
space:
mode:
authorMartin Fietz <Martin.Fietz@gmail.com>2016-06-30 19:34:36 +0200
committerGitHub <noreply@github.com>2016-06-30 19:34:36 +0200
commita806d58966bca19cb89ca0b2b2d287f2611c3e36 (patch)
tree54f866c084f2abd0dd9269bff3503987b469cdac /core/src/main/java
parent54f4ad7ba0db7f555449a4c666be9394841c72ce (diff)
parentbfe7cadd15d44b925ec17bb1bfd3c95e9e498dae (diff)
downloadAntennaPod-a806d58966bca19cb89ca0b2b2d287f2611c3e36.zip
Merge pull request #2053 from MeirSD/develop
Add preliminary support for Android Auto by changing PlaybackService …
Diffstat (limited to 'core/src/main/java')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java17
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java99
2 files changed, 111 insertions, 5 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
index b8b154ff0..64d4d14fd 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java
@@ -7,6 +7,8 @@ import android.media.MediaMetadataRetriever;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
+import android.support.v4.media.MediaBrowserCompat;
+import android.support.v4.media.MediaDescriptionCompat;
import java.util.Date;
import java.util.List;
@@ -148,6 +150,21 @@ public class FeedMedia extends FeedFile implements Playable {
}
/**
+ * Returns a MediaItem representing the FeedMedia object.
+ * This is used by the MediaBrowserService
+ */
+ public MediaBrowserCompat.MediaItem getMediaItem() {
+ Playable p = this;
+ MediaDescriptionCompat description = new MediaDescriptionCompat.Builder()
+ .setMediaId(String.valueOf(id))
+ .setTitle(p.getEpisodeTitle())
+ .setDescription(p.getFeedTitle())
+ .setSubtitle(p.getFeedTitle())
+ .build();
+ return new MediaBrowserCompat.MediaItem(description, MediaBrowserCompat.MediaItem.FLAG_PLAYABLE);
+ }
+
+ /**
* Uses mimetype to determine the type of media.
*/
public MediaType getMediaType() {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
index 88b2c70de..10386a423 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
@@ -17,10 +17,15 @@ import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.Build;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.Vibrator;
import android.preference.PreferenceManager;
+import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
+import android.support.v4.media.MediaBrowserCompat;
+import android.support.v4.media.MediaBrowserServiceCompat;
+import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
@@ -37,6 +42,7 @@ import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.Target;
import java.util.List;
+import java.util.ArrayList;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
@@ -51,6 +57,7 @@ import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
+import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.util.IntList;
@@ -62,7 +69,7 @@ import de.danoeh.antennapod.core.util.playback.Playable;
/**
* Controls the MediaPlayer that plays a FeedMedia-file
*/
-public class PlaybackService extends Service {
+public class PlaybackService extends MediaBrowserServiceCompat {
public static final String FORCE_WIDGET_UPDATE = "de.danoeh.antennapod.FORCE_WIDGET_UPDATE";
public static final String STOP_WIDGET_UPDATE = "de.danoeh.antennapod.STOP_WIDGET_UPDATE";
/**
@@ -194,7 +201,7 @@ public class PlaybackService extends Service {
private PlaybackServiceFlavorHelper flavorHelper;
/**
- * Only used for Lollipop notifications.
+ * Used for Lollipop notifications, Android Wear, and Android Auto.
*/
private MediaSessionCompat mediaSession;
@@ -202,8 +209,6 @@ public class PlaybackService extends Service {
private static volatile MediaType currentMediaType = MediaType.UNKNOWN;
- private final IBinder mBinder = new LocalBinder();
-
public class LocalBinder extends Binder {
public PlaybackService getService() {
return PlaybackService.this;
@@ -248,6 +253,8 @@ public class PlaybackService extends Service {
Log.d(TAG, "Service created.");
isRunning = true;
+ registerReceiver(autoStateUpdated, new IntentFilter(
+ "com.google.android.gms.car.media.STATUS"));
registerReceiver(headsetDisconnected, new IntentFilter(
Intent.ACTION_HEADSET_PLUG));
registerReceiver(shutdownReceiver, new IntentFilter(
@@ -277,6 +284,7 @@ public class PlaybackService extends Service {
PendingIntent buttonReceiverIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mediaSession = new MediaSessionCompat(getApplicationContext(), TAG, eventReceiver, buttonReceiverIntent);
+ setSessionToken(mediaSession.getSessionToken());
try {
mediaSession.setCallback(sessionCallback);
@@ -290,6 +298,16 @@ public class PlaybackService extends Service {
npe.printStackTrace();
}
+ List<MediaSessionCompat.QueueItem> queueItems = new ArrayList<>();
+ try {
+ for (FeedItem feedItem: taskManager.getQueue()) {
+ queueItems.add(new MediaSessionCompat.QueueItem(feedItem.getMedia().getMediaItem().getDescription(), feedItem.getId()));
+ }
+ mediaSession.setQueue(queueItems);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
flavorHelper.initializeMediaPlayer(PlaybackService.this);
mediaSession.setActive(true);
@@ -308,6 +326,7 @@ public class PlaybackService extends Service {
if (mediaSession != null) {
mediaSession.release();
}
+ unregisterReceiver(autoStateUpdated);
unregisterReceiver(headsetDisconnected);
unregisterReceiver(shutdownReceiver);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
@@ -324,9 +343,48 @@ public class PlaybackService extends Service {
}
@Override
+ public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
+ Log.d(TAG, "OnGetRoot: clientPackageName=" + clientPackageName +
+ "; clientUid=" + clientUid + " ; rootHints=" + rootHints);
+ return new BrowserRoot(
+ getResources().getString(R.string.app_name), // Name visible in Android Auto
+ null); // Bundle of optional extras
+ }
+
+ private MediaBrowserCompat.MediaItem createBrowsableMediaItemForRoot() {
+ MediaDescriptionCompat description = new MediaDescriptionCompat.Builder()
+ .setMediaId(getResources().getString(R.string.queue_label))
+ .setTitle(getResources().getString(R.string.queue_label))
+ .build();
+ return new MediaBrowserCompat.MediaItem(description,
+ MediaBrowserCompat.MediaItem.FLAG_BROWSABLE);
+ }
+
+ @Override
+ public void onLoadChildren(String parentId,
+ Result<List<MediaBrowserCompat.MediaItem>> result) {
+ Log.d(TAG, "OnLoadChildren: parentMediaId=" + parentId);
+ List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<MediaBrowserCompat.MediaItem>();
+ if (parentId.equals(getResources().getString(R.string.app_name))) {
+ // Root List
+ mediaItems.add(createBrowsableMediaItemForRoot());
+ } else if (parentId.equals(getResources().getString(R.string.queue_label))){
+ // Child List
+ try {
+ for (FeedItem feedItem: taskManager.getQueue()) {
+ mediaItems.add(feedItem.getMedia().getMediaItem());
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ result.sendResult(mediaItems);
+ }
+
+ @Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "Received onBind event");
- return mBinder;
+ return super.onBind(intent);
}
@Override
@@ -1221,6 +1279,22 @@ public class PlaybackService extends Service {
}
}
+ private final BroadcastReceiver autoStateUpdated = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String status = intent.getStringExtra("media_connection_status");
+ boolean isConnectedToCar = "media_connected".equals(status);
+ Log.d(TAG, "Received Auto Connection update: " + status);
+ if(!isConnectedToCar) {
+ Log.d(TAG, "Car was unplugged during playback.");
+ pauseIfPauseOnDisconnect();
+ } else {
+ mediaPlayer.setStartWhenPrepared(true);
+ mediaPlayer.prepare();
+ }
+ }
+ };
+
/**
* Pauses playback when the headset is disconnected and the preference is
* set
@@ -1500,6 +1574,21 @@ public class PlaybackService extends Service {
}
@Override
+ public void onPlayFromMediaId(String mediaId, Bundle extras) {
+ Log.d(TAG, "onPlayFromMediaId: mediaId: " + mediaId + " extras: " + extras.toString());
+ FeedMedia p = DBReader.getFeedMedia(Long.parseLong(mediaId));
+ if(p != null) {
+ mediaPlayer.playMediaObject(p, !p.localFileAvailable(), true, true);
+ }
+ }
+
+ @Override
+ public void onPlayFromSearch (String query, Bundle extras) {
+ //Until we parse the query just play from queue
+ onPlay();
+ }
+
+ @Override
public void onPause() {
Log.d(TAG, "onPause()");
if (getStatus() == PlayerStatus.PLAYING) {