Day21 Plugin 从零开始到上架 - 取得权杖(Android)

取得授权码後,我们就能准备取得我们的权杖了,我们需要再透过api 先取得短期权杖,再用短期权杖取得长期权杖,并储存下来供使用者之後使用,让我们照着官方的使用说明来实作吧

目标

取得长期权杖,并储存在本地端,以提供使用者之後能透过此权杖使用Instagram basic display 的api,Android 我们这边透过MVVM 的架构,让AccessTokenActivity能够取得长期权杖并储存在本地端

API:

interface ApiInstagramService {

    @FormUrlEncoded
    @POST("oauth/access_token")
    suspend fun getShortAccessTokenInfo(
        @Field("client_id") clientId: String,
        @Field("client_secret") clientSecret: String,
        @Field("code") code: String,
        @Field("grant_type") grantType: String,
        @Field("redirect_uri") redirectUri: String
    ): ShortAccessTokenInfo
}
interface GraphInstagramService {

    @GET("access_token")
    suspend fun getLongAccessTokenInfo(
        @Query("grant_type") grantType: String,
        @Query("client_secret") clientSecret: String,
        @Query("access_token") accessToken: String
    ): LongAccessTokenInfo

}

DataRepository:

    suspend fun getAccessToken(
        clientId: String,
        clientSecret: String,
        code: String,
        redirectUri: String
    ) {
        withContext(Dispatchers.IO) {
            getShortAccessToken(
                clientId,
                clientSecret,
                code,
                redirectUri
            )
        }
    }

    private suspend fun getShortAccessToken(
        clientId: String,
        clientSecret: String,
        code: String,
        redirectUri: String
    ) {
        try {
            val shortAccessTokenInfo = apiInstagramService.getShortAccessTokenInfo(
                clientId = clientId,
                clientSecret = clientSecret,
                code = code,
                grantType = "authorization_code",
                redirectUri = redirectUri
            )

            Log.d(TAG, "shortAccessTokenInfo = $shortAccessTokenInfo")

            preference.set(Constants.PREF_KEY_INSTAGRAM_USER_ID, shortAccessTokenInfo.userId)

            val currentTimeMillis: Long = System.currentTimeMillis()

            getLongAccessToken(shortAccessTokenInfo.accessToken, clientSecret, currentTimeMillis)
        } catch (exception: UnknownHostException) { // Request Api when no internet
            exception.printStackTrace()
            Log.e(TAG, "shortAccessTokenInfo exception = $exception")
            _accessTokenResult.postValue(false)
        } catch (exception: Exception) {
            exception.printStackTrace()
            Log.e(TAG, "shortAccessTokenInfo exception = $exception")
            _accessTokenResult.postValue(false)
        }
    }

    private suspend fun getLongAccessToken(
        shortAccessToken: String,
        clientSecret: String,
        currentTimeMillis: Long
    ) {
        try {
            val longAccessTokenInfo = graphInstagramService.getLongAccessTokenInfo(
                grantType = "ig_exchange_token",
                clientSecret = clientSecret,
                accessToken = shortAccessToken
            )

            val expiredTimeMillis = currentTimeMillis + longAccessTokenInfo.expiresIn

            preference.set(Constants.PREF_KEY_EXPIRED_MILLISECONDS, expiredTimeMillis)
            preference.set(Constants.PREF_KEY_ACCESS_TOKEN, longAccessTokenInfo.accessToken)

            _accessTokenResult.postValue(true)

        } catch (exception: UnknownHostException) { // Request Api when no internet
            exception.printStackTrace()
            Log.e(TAG, "getLongAccessToken exception = $exception")
            _accessTokenResult.postValue(false)
        } catch (exception: Exception) {
            exception.printStackTrace()
            Log.e(TAG, "getLongAccessToken exception = $exception")
            _accessTokenResult.postValue(false)
        }
    }

AccessTokenViewModel:

    fun getAssessToken(
        clientId: String,
        clientSecret: String,
        code: String,
        redirectUri: String
    ) {
        viewModelScope.launch {
            repository.getAccessToken(
                clientId,
                clientSecret,
                code,
                redirectUri
            )
        }
    }

<<:  Day 24: Data Protection on AWS

>>:  Day21 URLSession 01 - POST

数学案例说明WEB 3.0时代,不可避免遭遇的数值正确性-by a Java Devops

『电脑科学由於硬体的限制,存在计算的误差。从同一道数学问题,透过 程序解与手动解析解来观察此一现象最...

[Day 14] Leetcode 115. Distinct Subsequences (C++)

前言 今日挑战的题目是115. Distinct Subsequences,虽然是hard,但因为有...

Vue3 ( JsES6、this、指令、OptionAPI ) -1

1.v-mould写入、渲染 (1) (2) (3) (4) (5) (6) 重点: 1.阵列 与 ...

ASP.NET MVC 从入门到放弃(Day8) -C# try catch常见异常和自定义异常 using 介绍

接着来讲讲try catch 部分.... 一般来说是要避免程序因为出现错误讯息挂掉的处理方式......

【Day 09】C 的关系运算子与逻辑运算子

今天一开始,让我们先介绍一下,甚麽是关系运算子! 关系运算子 关系运算子顾名思义,就是用来比较两个变...