昨天我們設定好了OAuth 2.0憑證,今天我們來講如何在Android Studio使用OAuth 2.0連結我們的Google帳戶,APP會透過OAuth 2.0向用戶請求授權,然後用戶會登入並同意授權該應用程式存取其 Google 日曆的權限。之後應用程式會獲得訪問令牌(Access Token),用來代表用戶與 API 進行互動。
在build.gradle(APP)
中加入以下相依性
dependencies {
implementation("com.google.android.gms:play-services-auth:20.5.0")
implementation("com.google.api-client:google-api-client-android:1.33.0")
implementation("com.google.apis:google-api-services-calendar:v3-rev20190609-1.30.1")
implementation("com.google.oauth-client:google-oauth-client-jetty:1.33.0")
implementation("com.google.http-client:google-http-client-android:1.40.0")
implementation("com.google.http-client:google-http-client-gson:1.40.0")
}
AndroidManifest.xml
加入需要的權限:<?xml version="1.0" encoding="utf-8"?>
<manifest
//略
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<application
//略
<activity
//略
</activity>
</application>
</manifest>
下面我先將程式碼放上來,再來講解該程式碼的作用
package your com.example
import android.app.Activity
import android.content.Intent
import android.util.Log
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.GoogleSignInOptions
import com.google.android.gms.common.api.ApiException
import com.google.api.client.extensions.android.http.AndroidHttp
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential
import com.google.api.services.calendar.Calendar
import com.google.api.services.calendar.CalendarScopes
import com.google.api.client.json.gson.GsonFactory
class GoogleCalendarAuth(
private val activity: Activity,
private val onSignInSuccess: (Boolean) -> Unit
) {
companion object {
private const val RC_SIGN_IN = 1001
}
private var googleSignInClient = GoogleSignIn.getClient(
activity,
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestScopes(com.google.android.gms.common.api.Scope(CalendarScopes.CALENDAR))
.build()
)
private var calendarService: Calendar? = null
// 開始 Google 登入流程
fun signIn() {
val signInIntent = googleSignInClient.signInIntent
activity.startActivityForResult(signInIntent, RC_SIGN_IN)
}
// 在 onActivityResult 中處理登入結果
fun handleSignInResult(requestCode: Int, data: Intent?) {
if (requestCode == RC_SIGN_IN) {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
try {
val account = task.getResult(ApiException::class.java)
setupCalendarService(account)
Log.d("GoogleCalendarAuth", "Sign-in successful")
onSignInSuccess(true) // 成功時回調 true
} catch (e: ApiException) {
Log.e("GoogleCalendarAuth", "Sign-in failed, code=${e.statusCode}")
onSignInSuccess(false) // 失敗時回調 false
}
} else {
Log.d("GoogleCalendarAuth", "handleSignInResult not called")
}
}
// 設定 Google Calendar 服務
private fun setupCalendarService(account: GoogleSignInAccount?) {
val credential = GoogleAccountCredential.usingOAuth2(
activity, listOf(CalendarScopes.CALENDAR)
)
credential.selectedAccount = account?.account
calendarService = Calendar.Builder(
AndroidHttp.newCompatibleTransport(),
GsonFactory.getDefaultInstance(),
credential
).setApplicationName("YourAppName").build()
}
// 取得 Google Calendar 服務
fun getCalendarService(): Calendar? {
return calendarService
}
}
}
上面這段程式碼負責處理 Google Calendar 的登入與授權流程。在 Android 應用中,使用 GoogleSignInClient 讓使用者進行 Google 登入,並透過 onActivityResult 確認登入結果。登入成功後,會建立 Google Calendar API 服務實例,並將授權憑證 (GoogleAccountCredential) 設定給該服務。
這樣我們就完成一個簡單的Google Calendar API授權程式
接下來我們來檢測是否能成功運行
我們在MainActivity.kt
修改一下程式碼,程式碼如下
class MainActivity : ComponentActivity() {
private var googleCalendarAuth: GoogleCalendarAuth? = null // 初始化變數
private var loginSuccess = mutableStateOf(false) // 使用 mutableStateOf 追蹤登入狀態
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 初始化 GoogleCalendarAuth 並設定成功/失敗回調
googleCalendarAuth = GoogleCalendarAuth(this) { success ->
Log.d("MainActivity", "Sign-in result received: $success") // 確認是否收到回調
if (success) {
loginSuccess.value = true // 更新登入狀態
}
}
// 使用 Jetpack Compose 設定 UI
setContent {
MyApp()
}
}
@Composable
fun MyApp() {
val context = LocalContext.current // 取得當前的 Context
val isLoggedIn by loginSuccess // 使用 by 來觀察 mutableState
Column(modifier = Modifier.padding(16.dp)) {
if (!isLoggedIn) {
Button(onClick = {
googleCalendarAuth?.signIn()
}) {
Text(text = "Sign in to Google Calendar")
}
} else {
Text(text = "登入成功")
// 顯示登入成功的 Toast 訊息
LaunchedEffect(Unit) {
Toast.makeText(context, "登入成功", Toast.LENGTH_SHORT).show()
}
}
}
}
// 處理 Google 登入的回調
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
googleCalendarAuth?.handleSignInResult(requestCode, data) // 呼叫 GoogleCalendarAuth 處理登入結果
}
}
編譯結果如下
我們點擊Sign in to Google Calendar,APP程式將啟動 Google Sign-In 流程,並彈出一個 Google 登入頁面,要求你選擇一個 Google 帳戶並授權應用程式訪問 Google Calendar。如果你是在虛擬機上執行,通常會要求你先登入你的Google帳戶,如下圖
登入帳戶後,點擊Sign in to Google Calendar,畫面上的按鈕將被替換為登入成功同時,應該彈出一個Toast 訊息,顯示登入成功如下圖所示
同時我們可以點選Android Studio左下角的Logcat(左下角像貓貓的那個ICON),能夠看到我們的LOG訊息,如下圖
可以看到我們已經成功使用使用OAuth 2.0連結我們的Google帳戶了。
今天我們使用了OAuth 2.0連結我們的Google帳戶,明天我們會開始透過程式來讀取行事曆上的事件,並透過程式碼新增事件到我們的行事曆上,這邊向各位勘誤一下,昨天的建立OAuthID那邊最後輸入的套件名稱應改為com. example.a2024ironman
,如果沒有改成和build.gradle(APP)
中的applicationId = "com.example.a2024ironman"
一樣,在進行OAuth 2.0連結我們的Google帳戶時Logcat會報錯Sign-in failed, code=10
錯誤代碼code=10
代表 OAuth 2.0 客戶端設定錯誤,通常是由於 SHA-1 指紋或套件名稱配置錯誤,導致 Google API 無法驗證你的應用程式的身份。,昨天的內容我已經有修改過了,在這邊和大家勘誤一下,好的今天的內容就到這邊結束,感謝你能看到這邊,我們明天再見。