spotify / android-sdk

Spotify SDK for Android
https://developer.spotify.com/documentation/android/
Apache License 2.0
459 stars 119 forks source link

Combine App Remote and Authentication Library #227

Open vdaele opened 4 years ago

vdaele commented 4 years ago

In my Android app, I want to visualize the audio beats. By using the Quick Start I can get authorized and get notifications for the currently playing song which is a good starting point already.

But I see no API (yet?) to access the audio-analysis (to get info on the beats). So I guess I have to use the WEB api for audio analysis and hence I need the token and the trackId. I don't think I can get these from the App Remote so I'll have to authenticate using the Authentication Library which is fine with me.

But I would still like to use the PlayerApi/PlayerState (especially the subscription to it) of the App Remote because that is pretty convenient.

PS: I'm not sure this is the most appropriate place to ask questions but I didn't found a developer mailing list or something like that.

SDK Version:

0.7.0

Expected behaviour:

Actual behaviour:

romariomkk commented 4 years ago

@vdaele use both libraries, request token from Auth library, then SpotifyAppRemote.connect(), and afterward request for the audio analysis with the token via WebAPI. Be aware that I have got a case when a connection to Spotify's SpotifyAppRemote doesn't happen after 30 seconds of waiting. I have described it in my issue: https://github.com/spotify/android-sdk/issues/231

Subscription to PlayerState is utmostly awkward, and despite the same events may be received, they have got the patterns which, once researched and properly, should show the same state of the player as in the Spotify app itself.

vdaele commented 4 years ago

@romariomkk Thanks for your feedback and for the pointer to #231 ! This seems to work indeed. The only nuissance is that my ConnectionListener fails with a SpotifyConnectionTerminatedException after 10' (see #224). I'll investigate whether I can work around this.

romariomkk commented 4 years ago

@vdaele this is a common behavior with iOS platform. If no interaction takes place, then the IPC and Spotify's service disconnects and unbinds, with a detail that on iOS it takes place in 1 minute. I request the user to re-authenticate.

Nimmidev commented 4 years ago

@romariomkk i don't know if the "no interaction" hypothesis is true. On Android i have the exact same problem that i get the SpotifyConnectionTerminatedException after a few minute after the app started. But there is no more then maybe 20 seconds without any interaction or PlayerState subscription event.

romariomkk commented 4 years ago

@Nimmidev just to clarify: The disconnect of our app and subsequent reception of SpotifyConnectionTerminatedException takes place only if music isn't in playback state for some time(for us it's surely more than 20 seconds - about 1-2 minutes). But if playback is ongoing, this case isn't reproduced, even if the device was blocked.

Nimmidev commented 4 years ago

@romariomkk hmm thats weird. I just tried it three times and it seems i always get a SpotifyConnectionTerminatedException approx. after 5-7 minutes of playing music.

Edit: To prevent the issue and also to tackle other types of disconnects i wrapped the appRemote in a suspend function getter. Maybe this will help someone who has the same kinda problem:

suspend fun getAppRemote(): SpotifyAppRemote {
    if(!initialized) throw IllegalStateException("Spotify not initialized")

    if(connected) {
        Log.i("SpotifyConnection", "Cached App Remote")
        return appRemote
    }

    return suspendCoroutine { con ->
        Log.i("SpotifyConnection", "Reconnect and suspend")
        onConnectedCallbacks.add(Runnable {
            Log.i("SpotifyConnection", "Reconnected and resume")
            con.resume(appRemote)
        })
    }
}

The onConnectedCallbacks is just a List with Runnables that will be called once the connection is established. In the Connection.ConnectionListener.onFailure method add an automatic reconnect depending on the kind of Exception and other constraints that you have.

If anyone has a better solution i am happy to see it.