如何在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客户端配置里对应好。
- Postman用固定值
- 务必在Google Console的API库中启用Google Home Graph API,否则拿到的令牌没有权限访问设备控制接口。
Postman 快速获取令牌
- 打开Postman,新建请求,切换到Authorization标签页,类型选OAuth 2.0。
- 按以下内容填写配置:
- 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
- 点击Get New Access Token,跳转Google登录页面后,用Google Home设备的管理员账号登录并授权,Postman会自动帮你获取到access_token、refresh_token等。
- 验证:调用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
相关产品推荐
相关产品推荐

