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 streaming scope, 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 0.8.6. 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 14: Android 4.0 (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 21
    buildToolsVersion "21" // Note: this version should match the latest build-tools version
                           // that you installed in the SDK manager

    defaultConfig {
        applicationId "companydomain.applicationname"
        minSdkVersion 14
        targetSdkVersion 21
        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-beta9@aar'
    
    // This library handles music playback
    compile 'com.spotify.sdk:spotify-player:1.0.0-beta9@aar'
    
    // All other dependencies for your app should also be here:
    compile 'com.android.support:appcompat-v7:21.0.3'
}

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.

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.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.spotify.sdk.android.player.Spotify;
import com.spotify.sdk.android.player.ConnectionStateCallback;
import com.spotify.sdk.android.player.Player;
import com.spotify.sdk.android.player.PlayerNotificationCallback;
import com.spotify.sdk.android.player.PlayerState;

public class MainActivity extends Activity implements
        PlayerNotificationCallback, 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
    public void onLoggedIn() {
        Log.d("MainActivity", "User logged in");
    }

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

    @Override
    public void onLoginFailed(Throwable error) {
        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);
    }

    @Override
    public void onPlaybackEvent(EventType eventType, PlayerState playerState) {
        Log.d("MainActivity", "Playback event received: " + eventType.name());
    }

    @Override
    public void onPlaybackError(ErrorType errorType, String errorDetails) {
        Log.d("MainActivity", "Playback error received: " + errorType.name());
    }

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

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 Spotify Accounts Service will be open in the dialog, where the user will be asked to log in to authorize your application’s scopes.

When the authorization is finished, the Accounts Service will make a callback to your redirect URI. 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);
            mPlayer = Spotify.getPlayer(playerConfig, this, new Player.InitializationObserver() {
                @Override
                public void onInitialized(Player player) {
                    mPlayer.addConnectionStateCallback(MainActivity.this);
                    mPlayer.addPlayerNotificationCallback(MainActivity.this);
                    mPlayer.play("spotify:track:2TpxZ7JUBn3uw46aR7qd6V");
                }

                @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.

Note that in this code we have asked 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.play with a URI that we want to play. The play method understands some types of Spotify URIs, including playlists and individual tracks. For a complete list of supported URIs, see the documentation for the Player 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.player.Spotify;
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.Player;
import com.spotify.sdk.android.player.PlayerNotificationCallback;
import com.spotify.sdk.android.player.PlayerState;

public class MainActivity extends Activity implements
        PlayerNotificationCallback, 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 passed together with authentication result to the onAuthenticationResult callback
    // 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);
                mPlayer = Spotify.getPlayer(playerConfig, this, new Player.InitializationObserver() {
                    @Override
                    public void onInitialized(Player player) {
                        mPlayer.addConnectionStateCallback(MainActivity.this);
                        mPlayer.addPlayerNotificationCallback(MainActivity.this);
                        mPlayer.play("spotify:track:2TpxZ7JUBn3uw46aR7qd6V");
                    }

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

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

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

    @Override
    public void onLoginFailed(Throwable error) {
        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);
    }

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

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

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

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.