You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Postman或Java/Kotlin中获取Google API的OAuth2令牌控制谷歌家庭空调?

获取Google Home API的OAuth2令牌(Postman/Android Kotlin实现)

先补全必备参数

你目前的参数还缺两个关键项,另外要确认API启用状态:

  • client_secret:创建OAuth客户端ID时,Google Console会同步生成这个值,要么在下载的客户端配置JSON里,要么在客户端详情页能找到,没有它没法完成令牌交换。
  • redirect_uri:根据使用场景设置:
    • Postman用固定值 https://oauth.pstmn.io/v1/callback,必须提前在Google Console的OAuth客户端授权回调地址里添加这个URL。
    • Android用自定义scheme格式,比如 com.your.app.package:/oauth2callback,同样要在Google Console的Android客户端配置里对应好。
  • 务必在Google Console的API库中启用Google Home Graph API,否则拿到的令牌没有权限访问设备控制接口。

Postman 快速获取令牌

  1. 打开Postman,新建请求,切换到Authorization标签页,类型选OAuth 2.0。
  2. 按以下内容填写配置:
    • Grant Type:选Authorization Code
    • Callback URL:填 https://oauth.pstmn.io/v1/callback
    • Auth URL:填你已有的auth_uri(通常是https://accounts.google.com/o/oauth2/auth)
    • Access Token URL:填你已有的token_uri(通常是https://oauth2.googleapis.com/token)
    • Client ID:你的client_id
    • Client Secret:刚补的client_secret
    • Scope:必须填 https://www.googleapis.com/auth/homegraph,这是控制Google Home设备的核心权限,需要额外权限的话可以补充,比如https://www.googleapis.com/auth/devices.smartmanagement
  3. 点击Get New Access Token,跳转Google登录页面后,用Google Home设备的管理员账号登录并授权,Postman会自动帮你获取到access_token、refresh_token等。
  4. 验证:调用Home Graph API的接口(比如POST https://homegraph.googleapis.com/v1/devices:requestSync),在Headers里加Authorization: Bearer {你的access_token},看看能不能正常响应。

Android Kotlin 集成实现

1. 先配置Google Console

  • 添加Android类型的OAuth客户端,填写你的应用包名和SHA-1指纹(用./gradlew signingReport命令能获取到指纹)。
  • 设置redirect_uri为{你的应用包名}:/oauth2callback,比如com.example.homecontrol:/oauth2callback。

2. 依赖配置

在app模块的build.gradle中添加必要依赖:

dependencies {
    implementation 'com.google.android.gms:play-services-auth:20.7.0'
    implementation 'com.squareup.okhttp3:okhttp:4.12.0'
}

3. 实现授权流程

import android.content.Intent
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.api.Scope
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request

class MainActivity : AppCompatActivity() {
    private lateinit var googleSignInClient: GoogleSignInClient
    private val RC_SIGN_IN = 1001

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 配置Google登录,请求Home Graph权限
        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestScopes(Scope("https://www.googleapis.com/auth/homegraph"))
            .requestServerAuthCode("{你的client_id}", false)
            .build()

        googleSignInClient = GoogleSignIn.getClient(this, gso)

        // 绑定登录按钮点击事件
        findViewById<View>(R.id.btn_sign_in).setOnClickListener {
            val signInIntent = googleSignInClient.signInIntent
            startActivityForResult(signInIntent, RC_SIGN_IN)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == RC_SIGN_IN) {
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            val account = task.result
            account?.serverAuthCode?.let { authCode ->
                // 用授权码换取令牌
                exchangeAuthCodeForToken(authCode)
            }
        }
    }

    private fun exchangeAuthCodeForToken(authCode: String) {
        val client = OkHttpClient()
        val formBody = FormBody.Builder()
            .add("code", authCode)
            .add("client_id", "{你的client_id}")
            .add("client_secret", "{你的client_secret}")
            .add("redirect_uri", "{你的应用包名}:/oauth2callback")
            .add("grant_type", "authorization_code")
            .build()

        val request = Request.Builder()
            .url("{你的token_uri}") // 通常填https://oauth2.googleapis.com/token
            .post(formBody)
            .build()

        client.newCall(request).enqueue(object : okhttp3.Callback {
            override fun onFailure(call: okhttp3.Call, e: java.io.IOException) {
                // 处理请求失败逻辑,比如弹提示
            }

            override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
                val responseBody = response.body?.string()
                // 解析返回的JSON,拿到access_token、refresh_token、expires_in等参数
                // 可以用Gson或者JSONObject解析,之后就能用access_token调用Home Graph API了
            }
        })
    }
}

4. 刷新过期令牌

access_token有效期一般是1小时,过期后用refresh_token换取新的:

private fun refreshAccessToken(refreshToken: String) {
    val client = OkHttpClient()
    val formBody = FormBody.Builder()
        .add("refresh_token", refreshToken)
        .add("client_id", "{你的client_id}")
        .add("client_secret", "{你的client_secret}")
        .add("grant_type", "refresh_token")
        .build()

    val request = Request.Builder()
        .url("{你的token_uri}")
        .post(formBody)
        .build()

    client.newCall(request).enqueue(object : okhttp3.Callback {
        override fun onFailure(call: okhttp3.Call, e: java.io.IOException) {
            // 处理失败
        }

        override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
            val responseBody = response.body?.string()
            // 解析拿到新的access_token
        }
    })
}

内容的提问来源于stack exchange,提问作者Apuna12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 14:21:01