diff options
author | Martin Fietz <Martin.Fietz@gmail.com> | 2016-06-30 19:34:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-30 19:34:36 +0200 |
commit | a806d58966bca19cb89ca0b2b2d287f2611c3e36 (patch) | |
tree | 54f866c084f2abd0dd9269bff3503987b469cdac /core/src | |
parent | 54f4ad7ba0db7f555449a4c666be9394841c72ce (diff) | |
parent | bfe7cadd15d44b925ec17bb1bfd3c95e9e498dae (diff) | |
download | AntennaPod-a806d58966bca19cb89ca0b2b2d287f2611c3e36.zip |
Merge pull request #2053 from MeirSD/develop
Add preliminary support for Android Auto by changing PlaybackService …
Diffstat (limited to 'core/src')
-rw-r--r-- | core/src/main/AndroidManifest.xml | 10 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/feed/FeedMedia.java | 17 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java | 99 | ||||
-rw-r--r-- | core/src/main/res/drawable/ic_notification.png | bin | 0 -> 3887 bytes | |||
-rw-r--r-- | core/src/main/res/values/strings.xml | 1 |
5 files changed, 119 insertions, 8 deletions
diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index 4caad5f96..ee035c9fa 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -17,10 +17,14 @@ <service android:name=".service.download.DownloadService" android:enabled="true" /> - <service - android:name=".service.playback.PlaybackService" + <service android:name=".service.playback.PlaybackService" + android:label="@string/app_name" android:enabled="true" - android:exported="true" /> + android:exported="true"> + <intent-filter> + <action android:name="android.media.browse.MediaBrowserService"/> + </intent-filter> + </service> <service android:name=".service.GpodnetSyncService" android:enabled="true" /> 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) { diff --git a/core/src/main/res/drawable/ic_notification.png b/core/src/main/res/drawable/ic_notification.png Binary files differnew file mode 100644 index 000000000..8bd22b54a --- /dev/null +++ b/core/src/main/res/drawable/ic_notification.png diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index f1936b76e..783f6c1d9 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -4,6 +4,7 @@ tools:ignore="MissingTranslation"> <!-- Activitiy and fragment titles --> + <string name="app_name" translate="false">AntennaPod</string> <string name="feeds_label">Feeds</string> <string name="statistics_label">Statistics</string> <string name="add_feed_label">Add Podcast</string> |