This tutorial leads you step-by-step through the creation of a simple app that uses the Spotify Android SDK to play an audio track.

Please note: the Android SDK is currently a beta release; its content and functionality is likely to change significantly without warning. Note that by using Spotify developer tools, you accept our Developer Terms of Use.

About This Tutorial

This tutorial leads you step-by-step through the creation of a simple app that uses the Spotify Android SDK to play an audio track. We show you how to:

  • Set up an Android Studio project for your app,
  • Authenticate a user,
  • Play an audio stream from Spotify. (Premium accounts only)

The app we will create is very simple. It has just a single Activity created by Android Studio. When the app starts it authenticates the user, gets the user’s authorization to stream a track, and starts playing that track. The complexities of Android app development are beyond the scope of this tutorial; our aim is simply to help you set up your environment and project correctly and to make sure you can connect to the Spotify service. If you are new to developing Android apps, we recommend reading the tutorials on Google’s Android developer portal.

We will be calling several of the Spotify Android SDK functions in our code. Full documentation for these functions is available within the Android SDK’s download package on GitHub or online. The package also contains a README that contains important information about the SDK, including set-up information.

Preparing Your Environment

To use the Spotify Android SDK, the first thing you will need is a Spotify user account (Premium or Free). To get one, simply sign up at www.spotify.com.

Note: this tutorial makes use of the streamingscope, therefore the user who logs in must have a Spotify Premium account.

Next, download the Android Studio for your platform and install it using the default settings. You may also need to download and install a compatible Java SE Development Kit if you do not already have one installed on your system. Note that the Java Development Kit you install must match your operating system type, for example, 64-bit Windows user should download the 64-bit Java SE package.

This tutorial is based on Android Studio 1.5.1. If you are using a different version of Android Studio, please make sure your Gradle files are compatible with the version that you have installed.

Creating a New Project

Open Android Studio and create a New Project.

In this tutorial, the values that you enter here will be substituted in code examples with the values applicationname and companydomain.

Set the Minimum SDK version to “API level 15: Android 4.0.3 (Ice Cream Sandwich)”.

When you are asked to “Add an activity to Mobile”, select Blank Activity.

Give the activity the name MainActivity, the layout the name activity_main, and the title MainActivity.

These values will be used later in the code examples. If you chose different values you will need to modify the subsequent code accordingly.

Click Finish. (If you get a Windows security alert, click Allow Access.) Android Studio will now create your project.

If Android Studio fails to create the project, look in the “Messages” tab at the bottom of the screen. It is likely that you need to update or install extra SDK dependencies, such as the Android SDK Build-tools. Open the Android SDK Manager from Android Studio’s Tools > Android > SDK Manager menu option and check for and install any updates or dependencies.

Note: you may still have an error importing from Gradle; ignore this error for the moment.

Installing the Android SDK

Download the Spotify Android SDK framework zip file from GitHub and unzip it.

In a file explorer (not Android Studio), drag the unzipped spotify-auth-version.aar and spotify-player-version.aar files into the /app/libs directory in your project’s root directory.

In Android Studio, open the app directory (which can also be labelledModule: app) and then open thebuild.gradle file. Double check to make sure that you edit the gradle file that is located in the app directory. Change the contents of the file to the following:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1" // Note: this version should match the latest build-tools version
                               // that you installed in the SDK manager

    defaultConfig {
        applicationId "companydomain.applicationname"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

repositories {
    mavenCentral()
    flatDir {
        dirs 'libs'
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    
    // This library handles authentication and authorization
    compile 'com.spotify.sdk:spotify-auth:1.0.0-beta12@aar'
    
    // This library handles music playback
    compile 'com.spotify.sdk:spotify-player:1.0.0-beta12@aar'
    
    // All other dependencies for your app should also be here:
    compile 'com.android.support:appcompat-v7:23.1.1'
}

The values you provide in the code above (buildToolsVersion, applicationId, and the aar file version) must match the particulars of your installations. Don’t forget to add the flatDir entry to the repositories section. Otherwise Gradle will not be able to locate the aar.

Note that, as shown in the second “compile” line in the code above, the Gradle file dependency is identified by using a colon in place of the first dash of the aar file name. The colon is actually a separator between the parts of the dependency. You can find more about Gradle dependency syntax here: http://www.gradle.org/docs/current/userguide/dependency_management.html

After doing this, in Android Studio, select Tools > Android > Sync Project with Gradle Files. You should now have no error messages in the messages pane. If you still have error messages, troubleshoot the problem before continuing.

Registering Your Application

The Android SDK uses the OAuth endpoints provided by the Spotify Accounts Service to authenticate the application user and to authorize your application to access the Spotify service. You will need to register your application at My Applications and obtain a client ID.

When you register your app you will also need to white list a redirect URI that the Spotify Accounts Service will use to callback to your app after authorization:

setting-your-callback

The redirect URI should have the general form:

yourcustomprotocol://callback

Do not use https or http or other common protocols as a prefix, otherwise you will find that the callback opens your client’s web browser or other program — make the protocol prefix unique so that your app has a chance to listen for it.

Later, you will need to enter this redirect URI (and, separately, the protocol and callback address) in your application code.

Registering Application Fingerprints

To communicate with Spotify you need to register one or more fingerprints in My Applications page in the Developer Portal. This value is used to authenticate your application against Spotify client.

Creating a Development Fingerprint

You need to register a development fingerprint to be able to interact with Spotify in the debug version of your application.

It is possible to register multiple fingerprints for the application, which can be useful if there are more than one developer working with your app that wants to communicate with Spotify.

To generate the fingerprint run this on OS X:

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v | grep SHA1

On Windows run:

keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore -list -v | grep SHA1

Debug keystore doesn’t have a password. To learn more about signing the Android applications see the Android documentation.

The result of this command should look similar to this:

 SHA1: E7:47:B5:45:71:A9:B4:47:EA:AD:21:D7:7C:A2:8D:B4:89:1C:BF:75

Copy the fingerprint and save it in the provided field together with the package name of the debug version your application.

 

Creating a Release Fingerprint

The release version of the application is usually signed with a different certificate than the debug version. To be able to communicate with Spotify client after your application has been published, you need to register the release fingerprint in the My Applications section in the Developer Portal.

To generate the fingerprint on OS X run:

keytool -exportcert -alias <RELEASE_KEY_ALIAS> -keystore <RELEASE_KEYSTORE_PATH> -list -v | grep SHA1

On Windows run:

keytool -exportcert -alias <RELEASE_KEY_ALIAS> -keystore <RELEASE_KEYSTORE_PATH> -list -v | grep SHA1

The result of this command should look similar to this:

 SHA1: E7:47:B5:45:71:A9:B4:47:EA:AD:21:D7:7C:A2:8D:B4:89:1C:BF:75

Copy the fingerprint and save it in the provided field together with the package name of the release version of your application.

Creating the Application Code

We will put all of the code for our app in the MainActivity.java file (in /app/src/main/java/companydomain.applicationname). In Android Studio, open the MainActivity class and replace its contents with the following code:

package companydomain.applicationname;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.spotify.sdk.android.authentication.AuthenticationClient;
import com.spotify.sdk.android.authentication.AuthenticationRequest;
import com.spotify.sdk.android.authentication.AuthenticationResponse;
import com.spotify.sdk.android.player.Config;
import com.spotify.sdk.android.player.ConnectionStateCallback;
import com.spotify.sdk.android.player.Error;
import com.spotify.sdk.android.player.Player;
import com.spotify.sdk.android.player.PlayerEvent;
import com.spotify.sdk.android.player.Spotify;
import com.spotify.sdk.android.player.SpotifyPlayer;

public class MainActivity extends Activity implements 
    SpotifyPlayer.NotificationCallback, ConnectionStateCallback
{

    // TODO: Replace with your client ID
    private static final String CLIENT_ID = "yourclientid";
    // TODO: Replace with your redirect URI
    private static final String REDIRECT_URI = "yourcustomprotocol://callback";

    private Player mPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onPlaybackEvent(PlayerEvent playerEvent) {
        Log.d("MainActivity", "Playback event received: " + playerEvent.name());
        switch (playerEvent) {
            // Handle event type as necessary
            default:
                break;
        }
    }

    @Override
    public void onPlaybackError(Error error) {
        Log.d("MainActivity", "Playback error received: " + error.name());
        switch (error) {
            // Handle error type as necessary
            default:
                break;
        }
    }

    @Override
    public void onLoggedIn() {
        Log.d("MainActivity", "User logged in");
    }

    @Override
    public void onLoggedOut() {
        Log.d("MainActivity", "User logged out");
    }

    @Override
    public void onLoginFailed(int i) {
        Log.d("MainActivity", "Login failed");
    }

    @Override
    public void onTemporaryError() {
        Log.d("MainActivity", "Temporary error occurred");
    }

    @Override
    public void onConnectionMessage(String message) {
        Log.d("MainActivity", "Received connection message: " + message);
    }
}

Again, note that the values you enter (package name, client ID, redirect URI, ) must match the particulars of your installation: make sure you enter the correct values. If Android Studio highlights any of the above code lines with red underlines, mouse-over these lines to see the problems and fix them before moving forward.

Authenticating the User

Now we are ready to write the code that authenticates the user and gets authorization to access the user’s data. We can do this within the onCreate method. Modify your activity so that it contains following code:

// Request code that will be used to verify if the result comes from correct activity
// Can be any integer
private static final int REQUEST_CODE = 1337;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    AuthenticationRequest.Builder builder = new AuthenticationRequest.Builder(CLIENT_ID,
                                                                              AuthenticationResponse.Type.TOKEN,
                                                                              REDIRECT_URI);
    builder.setScopes(new String[]{"user-read-private", "streaming"});
    AuthenticationRequest request = builder.build();

    AuthenticationClient.openLoginActivity(this, REQUEST_CODE, request);
}

The setScopes method sets the list of scopes that your app needs the user to grant. In this example, we only need to see the user’s details (user-read-private) and to stream music (streaming). A full list of scopes can be found in Web API: Using Scopes.

The Android SDK uses the same authentication and authorization process as the Spotify Web API. For detailed information, see the Web API Authorization Guide.

When this method is executed, the user will be asked to log in to authorize your application’s scopes.

When the authorization is finished, the result will be delivered to the onActivityResult callback. Modify the method so that it looks like this:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    // Check if result comes from the correct activity
    if (requestCode == REQUEST_CODE) {
        AuthenticationResponse response = AuthenticationClient.getResponse(resultCode, intent);
        if (response.getType() == AuthenticationResponse.Type.TOKEN) {
            Config playerConfig = new Config(this, response.getAccessToken(), CLIENT_ID);
            Spotify.getPlayer(playerConfig, this, new SpotifyPlayer.InitializationObserver() {
                @Override
                public void onInitialized(SpotifyPlayer spotifyPlayer) {
                    mPlayer = spotifyPlayer;
                    mPlayer.addConnectionStateCallback(MainActivity.this);
                    mPlayer.addNotificationCallback(MainActivity.this);
                }

                @Override
                public void onError(Throwable throwable) {
                    Log.e("MainActivity", "Could not initialize player: " + throwable.getMessage());
                }
            });
        }
    }
}

In this method, we extract the OAuth access token provided to us by the callback, and pass it to a Config object that will be used to create the player.

We also get the player using Spotify class. For more information, see the SDK API reference documentation for the Spotify class.

@Override
public void onLoggedIn() {
    Log.d("MainActivity", "User logged in");

    mPlayer.playUri(null, "spotify:track:2TpxZ7JUBn3uw46aR7qd6V", 0, 0);
}

When the player is logged in we ask the player to play the Spotify track with the URI spotify:track:2TpxZ7JUBn3uw46aR7qd6V.

Interacting with the Spotify Android Player

When we have created the Spotify object, we can use that to get a reference to the player. The player runs in a separate thread from your app’s main thread, so all calls to it are asynchronous. It is therefore safe to call the player’s methods from the GUI thread. These calls are non-blocking and are re-dispatched for you to the correct thread.

Once the player has been initialized, it will start processing commands. Commands given to the player before initialization is complete will be queued and executed once it is ready. Again, all methods on the player are non-blocking, but in this case there may be some delay in execution.

Now we can play a song. From the initialization callback, we call mPlayer.playURI with a URI that we want to play. The playURI method understands some types of Spotify URIs, including playlists and individual tracks. For a complete list of supported URIs, see the documentation for the SpotifyPlayer class.

We’re almost done, but there’s one more very important thing that we need to do. We need to dispose of the Player when we are done with it. That is typically done in the onDestroy callback of your Activity or Fragment, which should look like this:

@Override
protected void onDestroy() {
    Spotify.destroyPlayer(this);
    super.onDestroy();
}

Because the Player uses native resources, and because multiple Fragments can each have a reference to the singleton instance of the Player, it is very important that you release your reference when destroyed.

Important! If you do not call Spotify.destroyPlayer when you are done with the Player, then your app will leak resources.

The completed code of MainActivity.java should now look like this, but with your own client ID and redirect URI:

// TutorialApp
// Created by Spotify on 25/02/14.
// Copyright (c) 2014 Spotify. All rights reserved.
package companydomain.applicationname;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.spotify.sdk.android.authentication.AuthenticationClient;
import com.spotify.sdk.android.authentication.AuthenticationRequest;
import com.spotify.sdk.android.authentication.AuthenticationResponse;
import com.spotify.sdk.android.player.Config;
import com.spotify.sdk.android.player.ConnectionStateCallback;
import com.spotify.sdk.android.player.Error;
import com.spotify.sdk.android.player.Player;
import com.spotify.sdk.android.player.PlayerEvent;
import com.spotify.sdk.android.player.Spotify;
import com.spotify.sdk.android.player.SpotifyPlayer;

public class MainActivity extends Activity implements 
    SpotifyPlayer.NotificationCallback, ConnectionStateCallback
{

    // TODO: Replace with your client ID
    private static final String CLIENT_ID = "yourclientid";
    // TODO: Replace with your redirect URI
    private static final String REDIRECT_URI = "yourcustomprotocol://callback";

    // Request code that will be used to verify if the result comes from correct activity
    // Can be any integer
    private static final int REQUEST_CODE = 1337;

    private Player mPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AuthenticationRequest.Builder builder = new AuthenticationRequest.Builder(CLIENT_ID,
                AuthenticationResponse.Type.TOKEN,
                REDIRECT_URI);
        builder.setScopes(new String[]{"user-read-private", "streaming"});
        AuthenticationRequest request = builder.build();

        AuthenticationClient.openLoginActivity(this, REQUEST_CODE, request);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);

        // Check if result comes from the correct activity
        if (requestCode == REQUEST_CODE) {
            AuthenticationResponse response = AuthenticationClient.getResponse(resultCode, intent);
            if (response.getType() == AuthenticationResponse.Type.TOKEN) {
                Config playerConfig = new Config(this, response.getAccessToken(), CLIENT_ID);
                Spotify.getPlayer(playerConfig, this, new SpotifyPlayer.InitializationObserver() {
                    @Override
                    public void onInitialized(SpotifyPlayer spotifyPlayer) {
                        mPlayer = spotifyPlayer;
                        mPlayer.addConnectionStateCallback(MainActivity.this);
                        mPlayer.addNotificationCallback(MainActivity.this);
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        Log.e("MainActivity", "Could not initialize player: " + throwable.getMessage());
                    }
                });
            }
        }
    }

    @Override
    protected void onDestroy() {
        // VERY IMPORTANT! This must always be called or else you will leak resources
        Spotify.destroyPlayer(this);
        super.onDestroy();
    }

    @Override
    public void onPlaybackEvent(PlayerEvent playerEvent) {
        Log.d("MainActivity", "Playback event received: " + playerEvent.name());
        switch (playerEvent) {
            // Handle event type as necessary
            default:
                break;
        }
    }

    @Override
    public void onPlaybackError(Error error) {
        Log.d("MainActivity", "Playback error received: " + error.name());
        switch (error) {
            // Handle error type as necessary
            default:
                break;
        }
    }

    @Override
    public void onLoggedIn() {
        Log.d("MainActivity", "User logged in");
        
        mPlayer.playUri(null, "spotify:track:2TpxZ7JUBn3uw46aR7qd6V", 0, 0);
    }

    @Override
    public void onLoggedOut() {
        Log.d("MainActivity", "User logged out");
    }

    @Override
    public void onLoginFailed(int i) {
        Log.d("MainActivity", "Login failed");
    }

    @Override
    public void onTemporaryError() {
        Log.d("MainActivity", "Temporary error occurred");
    }

    @Override
    public void onConnectionMessage(String message) {
        Log.d("MainActivity", "Received connection message: " + message);
    }
}

The example code also registers for playback and connection callbacks, which can be used make your app respond to events sent by the Spotify SDK. Registering for these callbacks is optional, but most apps will be interested in knowing about these events.

Updating the Application Manifest

Before we run the app we need to update its manifest. Open the /app/src/main/AndroidManifest.xml file and modify its contents as follows:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="companydomain.applicationname" >
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        
        </activity>
        
        <!-- Needed for LoginActivity to work -->
        <activity
            android:name="com.spotify.sdk.android.authentication.LoginActivity"
            android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
    
    </application>
</manifest>

Building and Running Your Project

Click Android Studio’s Run button to build and run your app. Android Studio may prompt you for a device or emulator which you would like to run the app on.

Tip: If you are having trouble getting your app to run, see the Debugging with Android Studio guide on Google’s Android developer page.

As soon as the app starts, it opens the Spotify authorization service login dialog. Log in using the credentials for you Spotify Premium account.

The data that the app wants to access is shown. Click the button that allows the app to access the Spotify API’s. The authorization service will then return a result with an authorization code.

Once the access token is returned, the app immediately creates a player object, displays the text “Hello World” and starts playback of the selected track. If you can hear the dulcet tones of Tania Bowra you have completed this tutorial.
Download the Spotify Android SDK from GitHub.

Feel free to experiment with the Android SDK beta and to report problems through the public issue tracker on GitHub. If you would like to give us feedback on this tutorial you can use the comment form below.