I am trying to use Spotify API. But as the given auth token expires every hour, so I have to post a request to API to get a new one. I found a code on the official website that shows how to do it.
var client_id = 'CLIENT_ID';
var client_secret = 'CLIENT_SECRET';
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: {
'Authorization': 'Basic ' (new Buffer(client_id ':' client_secret).toString('base64'))
},
form: {
grant_type: 'client_credentials'
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var token = body.access_token;
}
});
But I am new to retrofit and I don't know any js. So I don't know how can I convert this code to kotlin. can anyone help me out?
CodePudding user response:
Step 1 :Create interface named ApiInterface.kt.
interface ApiInterface {
@POST("token")
fun getToken(): Call<ResponseBody>
}
Step 2 : In your activity paste these functions
public static Retrofit getClient(final String token) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.addInterceptor(new NetInterceptor())
.addInterceptor(chain -> {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Basic " getBasicAuth(clientId, clientServer))
.build();
return chain.proceed(newRequest);
})
//.followRedirects(false)
//.followSslRedirects(false)
.connectTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build();
return new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
}
convert basic auth to base64
private fun getBasicAuth(client_id: String, client_secret: String): String {
val data = ("$client_id:$client_secret").toByteArray(StandardCharsets.UTF_8)
return Base64.encodeToString(data, Base64.DEFAULT)
}
Step : 3 Do an api call
private fun apiCall() {
val call = getClient()!!.create(ApiInterface::class.java).getToken()
call.enqueue(object : Callback<UserResponse> {
override fun onResponse(call: Call<UserResponse>, response: Response<UserResponse>) {
Toast.makeText(this@MainActivity, response.code().toString()
" " response.body().toString(), Toast.LENGTH_SHORT).show()
}
override fun onFailure(call: Call<UserResponse>, t: Throwable) {
Toast.makeText(this@MainActivity, t.localizedMessage!!.toString(),
Toast.LENGTH_SHORT).show()
}
})
}
Step 4 : call api in your onCreate() method.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
apiCall()
}
CodePudding user response:
after many hours of research, i was able to figure out. here is the interface:
@POST("api/token")
@FormUrlEncoded
fun getToken(
@Header("Authorization") auth: String,
@Header("Content-Type") content: String,
@Field(("grant_type")) grantType: String
): Call<Token>
here is the activity:
private fun getToken(id:String) {
val retrofit: Retrofit = Retrofit.Builder().baseUrl(TOKEN_URL)
.addConverterFactory(GsonConverterFactory.create()).build()
val service : TopTrackApi = retrofit.create(TopTrackApi::class.java)
val base64String = "Basic " get64BaseString("$clientID:$clientSECRET")
val listCall : Call<Token> = service.getToken(base64String,"application/x-www-form-urlencoded","client_credentials")
listCall.enqueue(object : Callback<Token> {
override fun onResponse(response: Response<Token>?, retrofit: Retrofit?) {
if (response?.body() != null) {
setUpRV(id,response.body().access_token)
}
if(response?.body() == null){
Log.i("Response!", "null response body /getToken")
}
}
override fun onFailure(t: Throwable?) {
Log.e("Error", t!!.message.toString())
}
})
}
fun get64BaseString(value:String):String{
return Base64.encodeToString(value.toByteArray(), Base64.NO_WRAP)
}