1
votes

In my android application, I am trying to get an artist's top ten tracks. I'm using a wrapper for the Spotify Web API. To get the artist's top ten tracks you have to provide the getArtistTopTrack(id) method with the artist's id.

Here's my code that is meant to do that:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_top_ten);

    Intent intent = getIntent();

    String artistID = "";
    artistID = intent.getExtras().getString("ID");

    FetchTopTenTracksTask topTenTracksTask = new FetchTopTenTracksTask();
    topTenTracksTask.execute(artistID);
}

private class FetchTopTenTracksTask extends AsyncTask<String, Void, Tracks> {

    @Override
    protected Tracks doInBackground(String... params) {
        SpotifyApi api = new SpotifyApi();
        SpotifyService spotify = api.getService();

        return spotify.getArtistTopTrack(params[0]);
    }

The error that I am getting is

E/AndroidRuntime(2882): FATAL EXCEPTION: AsyncTask #2
E/AndroidRuntime(2882): java.lang.RuntimeException: An error occured while executing doInBackground()

and it was caused by doInBackground. My thoughts are the bad request is caused by this line of code because I need to specify a country code for the search (the API requires this) but I don't know how to.

return spotify.getArtistTopTrack(params[0]);

The correct endpoint for getting an artist's top tracks is

GET https://api.spotify.com/v1/artists/{the artists id}/top-tracks?country={ISO 3166-1 alpha 2 country code}

But when I checked the LogCat to see what endpoint it was using it turned to be an incorrect one

D/Retrofit(2882): <--- HTTP 400 https://api.spotify.com/v1/artists/{the artist id}%3Fcountry%3DIE/top-tracks (59ms)

As you can see, the country code which is "IE" is appended to the artist id, like this: "%3Fcountry%3DIE". This is what is causing the error, because the request could not be understood by the server, due to malformed syntax.

Can someone show me how I can append "?country={country code}" to the endpoint, instead of having it right after the artist id?

2

2 Answers

1
votes

To provide a solution to my own question:

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

    listView = (ListView) findViewById(R.id.listView);

    Intent intent = getIntent();

    String artistID = "";
    artistID = intent.getExtras().getString("ID");

    FetchTopTenTracksTask topTenTracksTask = new FetchTopTenTracksTask();
    topTenTracksTask.execute(artistID);
}

private class FetchTopTenTracksTask extends AsyncTask<String, Void, Tracks> {

    @Override
    protected Tracks doInBackground(String... params) {

        try {
            String artistID = params[0];

            Map<String, Object> options = new Hashtable<String, Object>();
            options.put("country", "IE"); //Can be any country code here 

            SpotifyApi api = new SpotifyApi();
            SpotifyService spotify = api.getService();

            return spotify.getArtistTopTrack(artistID, options);
        }
        catch (RetrofitError retrofitError) {

            Log.d("Retrofit Error: ", retrofitError.toString());
        }
        return null;
    }

Here is where I got the solution.

0
votes

You can use,

import com.neovisionaries.i18n.CountryCode;

try{
....
CountryCode country = CountryCode.DE;
GetArtistsTopTracksRequest request = SpotifyApi.getInstance().getArtistsTopTracks(artistId, country).build();