Is it possible to control playback of the Spotify app from within another Android app? I'm only looking for track skipping functionality (forward and backward).
I'm aware of the Spotify Android SDK, but it seems to only allow skipping of tracks played by the SDK:
com.spotify.sdk.android.playback.NativeSpotifyException: Failed SpPlaybackSkipToPrev with error code 14 (The operation is not supported if the device is not the active playback device)
To clarify, both the actual Spotify app, and my own app are running on the same device
Quick answer - No, this isn't possible.
Here's how to do it:
This will try to play/pause Spotify. If it's not running it will start it and make it start playing.
public void nextSong() {
int keyCode = KeyEvent.KEYCODE_MEDIA_NEXT;
if (!isSpotifyRunning()) {
startMusicPlayer();
}
Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
intent.setPackage("com.spotify.music");
synchronized (this) {
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
getContext().sendOrderedBroadcast(intent, null);
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, keyCode));
getContext().sendOrderedBroadcast(intent, null);
}
}
public void playPauseMusic() {
int keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
if (!mAudioManager.isMusicActive() && !isSpotifyRunning()) {
startMusicPlayer();
}
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
i.setPackage("com.spotify.music");
synchronized (this) {
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
getContext().sendOrderedBroadcast(i, null);
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, keyCode));
getContext().sendOrderedBroadcast(i, null);
}
}
private void startMusicPlayer() {
Intent startPlayer = new Intent(Intent.ACTION_MAIN);
startPlayer.setPackage("com.spotify.music");
startPlayer.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(startPlayer);
if (mMusicPlayerStartTimer != null) {
mMusicPlayerStartTimer.cancel();
}
mMusicPlayerStartTimer = new Timer("MusicPlayerStartTimer", true);
mMusicPlayerStartTimer.schedule(new MusicPlayerStartTimerTask(), DateUtils.SECOND_IN_MILLIS, DateUtils.SECOND_IN_MILLIS);
}
private boolean isSpotifyRunning() {
Process ps = null;
try {
String[] cmd = {
"sh",
"-c",
"ps | grep com.spotify.music"
};
ps = Runtime.getRuntime().exec(cmd);
ps.waitFor();
return ps.exitValue() == 0;
} catch (IOException e) {
Log.e(DEBUG_TAG, "Could not execute ps", e);
} catch (InterruptedException e) {
Log.e(DEBUG_TAG, "Could not execute ps", e);
} finally {
if (ps != null) {
ps.destroy();
}
}
return false;
}
private class MusicPlayerStartTimerTask extends TimerTask {
@Override
public void run() {
if (isSpotifyRunning()) {
playPauseMusic(null);
cancel();
}
}
}
EDIT: Added full example code
Yes, you can control playback using the RemoteController classes, or if using Lollipop, the MediaController classes, or if supporting L and earlier, then the MediaControllerCompat classes.
Then perform dispatchMediaButtonEvent() with KEYCODE_MEDIA_NEXT.