Cigogne  Eveillée
Cigogne Eveillée

Reputation: 2208

Control playback of the Spotify app from another Android app?

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

Upvotes: 5

Views: 3453

Answers (3)

Auras
Auras

Reputation: 7586

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

Upvotes: 8

barkside
barkside

Reputation: 3961

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.

Upvotes: 1

Michael Thelin
Michael Thelin

Reputation: 4830

Quick answer - No, this isn't possible.

Upvotes: -3

Related Questions