diff --git a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisMediaSession.java b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisMediaSession.java
index 30ebd8e3..d710e917 100644
--- a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisMediaSession.java
+++ b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisMediaSession.java
@@ -16,7 +16,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
-*/
+ */
package org.kde.kdeconnect.Plugins.MprisPlugin;
@@ -31,17 +31,21 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.preference.PreferenceManager;
+import android.service.notification.StatusBarNotification;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
+import android.util.Pair;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.Helpers.NotificationHelper;
+import org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationReceiver;
import org.kde.kdeconnect_tp.R;
import java.util.HashSet;
+import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.core.app.TaskStackBuilder;
import androidx.media.app.NotificationCompat.MediaStyle;
@@ -54,12 +58,14 @@ import androidx.media.app.NotificationCompat.MediaStyle;
* - The media session (via MediaSessionCompat; for lock screen control on
* older Android version. And in the future for lock screen album covers)
*/
-public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceChangeListener {
+public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceChangeListener, NotificationReceiver.NotificationListener {
private final static int MPRIS_MEDIA_NOTIFICATION_ID = 0x91b70463; // echo MprisNotification | md5sum | head -c 8
private final static String MPRIS_MEDIA_SESSION_TAG = "org.kde.kdeconnect_tp.media_session";
private static final MprisMediaSession instance = new MprisMediaSession();
+ private boolean spotifyRunning;
+
public static MprisMediaSession getInstance() {
return instance;
}
@@ -132,6 +138,19 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh
mpris.setPlayerListUpdatedHandler("media_notification", mediaNotificationHandler);
mpris.setPlayerStatusUpdatedHandler("media_notification", mediaNotificationHandler);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ NotificationReceiver.RunCommand(context, service -> {
+
+ service.addListener(MprisMediaSession.this);
+
+ boolean serviceReady = service.isConnected();
+
+ if (serviceReady) {
+ onListenerConnected(service);
+ }
+ });
+ }
+
updateMediaNotification();
}
@@ -164,52 +183,62 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh
* @param service The background service
*/
private void updateCurrentPlayer(BackgroundService service) {
- Device device = null;
- MprisPlugin.MprisPlayer playing = null;
+ Pair player = findPlayer(service);
+ //Update the last-displayed device and player
+ notificationDevice = player.first == null ? null : player.first.getDeviceId();
+ notificationPlayer = player.second;
+ }
+
+ private Pair findPlayer(BackgroundService service) {
//First try the previously displayed player
- if (notificationDevice != null && mprisDevices.contains(notificationDevice) && notificationPlayer != null) {
- device = service.getDevice(notificationDevice);
- }
- MprisPlugin mpris = null;
- if (device != null) {
- mpris = device.getPlugin(MprisPlugin.class);
- }
- if (mpris != null) {
- playing = mpris.getPlayerStatus(notificationPlayer.getPlayer());
- }
+ if (notificationDevice != null && mprisDevices.contains(notificationDevice)) {
+ Device device = service.getDevice(notificationDevice);
- //If nonexistant or not playing, try a different player for the same device
- if ((playing == null || !playing.isPlaying()) && mpris != null) {
- MprisPlugin.MprisPlayer playingPlayer = mpris.getPlayingPlayer();
+ if (device != null && device.isPluginEnabled("MprisPlugin")) {
+ if (shouldShowPlayer(notificationPlayer) && notificationPlayer.isPlaying()){
+ return new Pair<>(device, notificationPlayer);
+ }
- //Only replace the previously found player if we really found one
- if (playingPlayer != null) {
- playing = playingPlayer;
- }
- }
-
- //If nonexistant or not playing, try a different player for another device
- if (playing == null || !playing.isPlaying()) {
- for (Device otherDevice : service.getDevices().values()) {
- //First, check if we actually display notification for this device
- if (!mprisDevices.contains(otherDevice.getDeviceId())) continue;
- mpris = otherDevice.getPlugin(MprisPlugin.class);
- if (mpris == null) continue;
-
- MprisPlugin.MprisPlayer playingPlayer = mpris.getPlayingPlayer();
- //Only replace the previously found player if we really found one
- if (playingPlayer != null) {
- playing = playingPlayer;
- device = otherDevice;
- break;
+ // Try a different player for the same device
+ MprisPlugin.MprisPlayer player = getPlayerFromDevice(device);
+ if (player != null) {
+ return new Pair<>(device, player);
}
}
}
- //Update the last-displayed device and player
- notificationDevice = device == null ? null : device.getDeviceId();
- notificationPlayer = playing;
+ // Try a different player from another device
+ for (Device otherDevice : service.getDevices().values()) {
+ MprisPlugin.MprisPlayer player = getPlayerFromDevice(otherDevice);
+ if (player != null) {
+ return new Pair<>(otherDevice, player);
+ }
+ }
+ return new Pair<>(null, null);
+ }
+
+ private MprisPlugin.MprisPlayer getPlayerFromDevice(Device device) {
+
+ if (!mprisDevices.contains(device.getDeviceId()))
+ return null;
+
+ MprisPlugin plugin = device.getPlugin(MprisPlugin.class);
+
+ if (plugin == null) {
+ return null;
+ }
+
+ MprisPlugin.MprisPlayer player = plugin.getPlayingPlayer();
+ if (shouldShowPlayer(player)) {
+ return player;
+ }
+
+ return null;
+ }
+
+ private boolean shouldShowPlayer(MprisPlugin.MprisPlayer player) {
+ return player != null && !(player.isSpotify() && spotifyRunning);
}
/**
@@ -316,7 +345,7 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh
*/
PendingIntent piOpenActivity = TaskStackBuilder.create(context)
.addNextIntentWithParentStack(iOpenActivity)
- .getPendingIntent(Build.VERSION.SDK_INT > 15 ? 0 : (int)System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT);
+ .getPendingIntent(Build.VERSION.SDK_INT > 15 ? 0 : (int) System.currentTimeMillis(), PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notification = new NotificationCompat.Builder(context, NotificationHelper.Channels.MEDIA_CONTROL);
@@ -433,4 +462,33 @@ public class MprisMediaSession implements SharedPreferences.OnSharedPreferenceCh
notificationPlayer = player;
updateMediaNotification();
}
+
+ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
+ @Override
+ public void onNotificationPosted(StatusBarNotification n) {
+ if (n.getPackageName().equals("com.spotify.music")) {
+ spotifyRunning = true;
+ updateMediaNotification();
+ }
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
+ @Override
+ public void onNotificationRemoved(StatusBarNotification n) {
+ if (n.getPackageName().equals("com.spotify.music")) {
+ spotifyRunning = false;
+ updateMediaNotification();
+ }
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
+ @Override
+ public void onListenerConnected(NotificationReceiver service) {
+ for (StatusBarNotification n : service.getActiveNotifications()) {
+ if (n.getPackageName().equals("com.spotify.music")) {
+ spotifyRunning = true;
+ updateMediaNotification();
+ }
+ }
+ }
}
diff --git a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java
index d60c7b69..30fe977e 100644
--- a/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java
+++ b/src/org/kde/kdeconnect/Plugins/MprisPlugin/MprisPlugin.java
@@ -87,7 +87,7 @@ public class MprisPlugin extends Plugin {
return player;
}
- private boolean isSpotify() {
+ boolean isSpotify() {
return getPlayer().toLowerCase().equals("spotify");
}