diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index c12b20c60..a6abd06fb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -11,8 +11,14 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.media.MediaMetadata; +import android.media.session.MediaController; +import android.media.session.MediaSession; +import android.media.session.PlaybackState; +import android.os.Build; import android.os.Bundle; import android.os.PowerManager; +import android.provider.MediaStore; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.support.v4.app.NotificationCompat; @@ -26,6 +32,7 @@ import java.util.List; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; +import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; @@ -183,10 +190,8 @@ public class NotificationListener extends NotificationListenerService { String source = sbn.getPackageName(); Notification notification = sbn.getNotification(); - if (source.equals("au.com.shiftyjelly.pocketcasts")) { - if (handlePocketCastNotification(notification)) - return; - } + if (handleMediaSessionNotification(notification)) + return; if ((notification.flags & Notification.FLAG_ONGOING_EVENT) == Notification.FLAG_ONGOING_EVENT) { return; @@ -318,32 +323,69 @@ public class NotificationListener extends NotificationListenerService { } /** - * Try to handle pocket cast notifications that tell info about the current play state. + * Try to handle media session notifications that tell info about the current play state. + * * @param notification The notification to handle. * @return true if notification was handled, false otherwise */ - public boolean handlePocketCastNotification(Notification notification) { + public boolean handleMediaSessionNotification(Notification notification) { + + // this code requires Android 5.0 or newer + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + return false; + } + MusicSpec musicSpec = new MusicSpec(); + MusicStateSpec stateSpec = new MusicStateSpec(); Bundle extras = notification.extras; if (extras == null) return false; - CharSequence title = extras.getCharSequence(Notification.EXTRA_TITLE); - if (title != null) - musicSpec.artist = title.toString(); - if (extras.containsKey(Notification.EXTRA_TEXT)) { - CharSequence contentCS = extras.getCharSequence(Notification.EXTRA_TEXT); - if (contentCS != null) - musicSpec.track = contentCS.toString(); + if (extras.get(Notification.EXTRA_MEDIA_SESSION) == null) + return false; + + MediaController c; + try { + c = new MediaController(getApplicationContext(), (MediaSession.Token) extras.get(Notification.EXTRA_MEDIA_SESSION)); + } catch (NullPointerException e) { + return false; } - musicSpec.album = "unknown"; + PlaybackState s = c.getPlaybackState(); + stateSpec.position = (int)s.getPosition(); + stateSpec.playRate = Math.round(100 * s.getPlaybackSpeed()); + stateSpec.repeat = 1; + stateSpec.shuffle = 1; + switch (s.getState()) { + case PlaybackState.STATE_PLAYING: + stateSpec.state = 0x01; + break; + case PlaybackState.STATE_STOPPED: + case PlaybackState.STATE_PAUSED: + stateSpec.state = 0x00; + break; + default: + stateSpec.state = 0x04; + break; + } - LOG.info("handlePocketCastsNotification: artist " + musicSpec.artist + ", track " + musicSpec.track); + MediaMetadata d = c.getMetadata(); + if (d == null) + return false; + if (d.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) + musicSpec.artist = d.getString(MediaMetadata.METADATA_KEY_ARTIST); + if (d.containsKey(MediaMetadata.METADATA_KEY_ALBUM)) + musicSpec.album = d.getString(MediaMetadata.METADATA_KEY_ALBUM); + if (d.containsKey(MediaMetadata.METADATA_KEY_TITLE)) + musicSpec.track = d.getString(MediaMetadata.METADATA_KEY_TITLE); + if (d.containsKey(MediaMetadata.METADATA_KEY_DURATION)) + musicSpec.duration = (int)d.getLong(MediaMetadata.METADATA_KEY_DURATION) / 1000; // finally, tell the device about it GBApplication.deviceService().onSetMusicInfo(musicSpec); + GBApplication.deviceService().onSetMusicState(stateSpec); + return true; }