ก่อนที่จะใช้ Home API ใดๆ สำหรับ Android คุณต้องเริ่มต้นใช้งาน Home ใน
แอป ในขั้นตอนนี้ คุณจะสร้างอินสแตนซ์ Singleton ของ
Home สำหรับบริบทในเครื่อง
ควรมีอินสแตนซ์ Home ที่ใช้งานอยู่เพียงอินสแตนซ์เดียวในแต่ละครั้ง
นี่คือจุดเริ่มต้นของ Home API และยังเกี่ยวข้องกับการประกาศลักษณะและประเภทอุปกรณ์ที่คุณต้องการใช้กับ Device &Structure และ Automation API หากคุณเพิ่งเริ่มต้นใช้งานระบบนิเวศ Google Home และไม่แน่ใจว่าจะลงทะเบียนลักษณะหรือประเภทอุปกรณ์ใด เราได้แนะนำลักษณะและประเภทอุปกรณ์ที่พบบ่อยที่สุดบางส่วนไว้ในคู่มือนี้
สร้างอินสแตนซ์ Home
เริ่มต้นด้วยการนำเข้าแพ็กเกจต่อไปนี้ลงในแอป
import android.content.Context
import com.google.home.FactoryRegistry
import com.google.home.HomeConfig
import com.google.home.Home
วิธีเริ่มต้นใช้งาน Home API
รับข้อมูลอ้างอิงไปยัง
Applicationบริบท บริบทนี้ไม่ขึ้นอยู่กับวงจรกิจกรรมใดๆ และจะใช้งานได้ตราบใดที่แอปยังทำงานอยู่ คุณรับข้อมูลอ้างอิงนี้ได้โดยเรียกgetApplicationContext()ภายในActivityหรือServiceดังนี้val context = getApplicationContext()สร้าง
FactoryRegistryอินสแตนซ์ ที่มีลักษณะและประเภทอุปกรณ์ทั้งหมดที่คุณต้องการใช้ในแอปสำหรับคู่มือนี้ เราได้แนะนำลักษณะและประเภทอุปกรณ์ที่พบบ่อยบางอย่าง (ประเภทอุปกรณ์ไฟ ปลั๊ก เซ็นเซอร์ สวิตช์ และตัวควบคุมอุณหภูมิ ลักษณะการแสดงข้อมูลและการสนับสนุนสำหรับระบบอัตโนมัติ) ในกรณีที่คุณไม่แน่ใจว่าต้องการลักษณะและประเภทอุปกรณ์ใด ดูข้อมูลเพิ่มเติมได้ที่ การลงทะเบียนลักษณะและประเภทอุปกรณ์
val registry = FactoryRegistry( traits = listOf( AirQuality, AreaAttendanceState, AreaPresenceState, AssistantBroadcast, AssistantFulfillment, BooleanState, ColorControl, ExtendedColorControl, FlowMeasurement, IlluminanceMeasurement, LevelControl, Notification, OccupancySensing, OnOff, RelativeHumidityMeasurement, Switch, TemperatureMeasurement, Thermostat), types = listOf( AirQualitySensorDevice, ColorDimmerSwitchDevice, ColorTemperatureLightDevice, ContactSensorDevice, DimmableLightDevice, DimmablePlugInUnitDevice, DimmerSwitchDevice, ExtendedColorLightDevice, FlowSensorDevice, GenericSwitchDevice, HumiditySensorDevice, LightSensorDevice, OccupancySensorDevice, OnOffLightDevice, OnOffLightSwitchDevice, OnOffPluginUnitDevice, OnOffSensorDevice, SpeakerDevice, TemperatureSensorDevice, ThermostatDevice))คุณต้องมีคำสั่งนำเข้าสำหรับลักษณะและประเภทอุปกรณ์แต่ละรายการที่ลงทะเบียนไว้ที่นี่ (ควรแจ้งให้คุณเพิ่มคำสั่งเหล่านี้)Android Studio
สร้างอินสแตนซ์
HomeConfigโดยใช้Dispatchers.IOบริบทโครูทีนและอินสแตนซ์รีจิสทรีval homeConfig = HomeConfig( coroutineContext = Dispatchers.IO, factoryRegistry = registry)สุดท้าย ให้สร้างอินสแตนซ์ Singleton ของ
Homeซึ่งเป็นจุดเริ่มต้นของ API โดยใช้บริบทและHomeConfigval homeManager: HomeClient = Home.getClient(context, homeConfig)
คุณต้องสร้างอินสแตนซ์ Singleton
ของ Home เท่านั้น โดยการใส่ไว้ในการประกาศ ออบเจ็กต์
เพื่อหลีกเลี่ยงข้อผิดพลาดเกี่ยวกับเซสชันที่ไม่ถูกต้อง
ตัวอย่างเช่น แอปตัวอย่าง จะทำดังนี้
internal object HomeClientModule {
@Provides
@Singleton
fun provideHomeClient(@ApplicationContext context: Context): HomeClient {
return Home.getClient(
context,
HomeConfig(
coroutineContext = IODispatcherModule.provideIoDispatcher(),
factoryRegistry = registry,
),
)
}
}
การลงชื่อเข้าใช้ Google ที่แอปเป็นผู้เริ่ม
คุณอาจต้องการจัดการการตรวจสอบสิทธิ์ Google ของผู้ใช้ภายในแอป การทำเช่นนี้จะช่วยให้คุณใช้บัญชีผู้ใช้เดียวกันในบริการต่างๆ ของ Google เช่น Google Home, ไดรฟ์, Maps และอื่นๆ
การลงชื่อเข้าใช้ Google ที่แอปเป็นผู้เริ่มจะช่วยให้คุณได้รับอินสแตนซ์ HomeClient ที่เชื่อมโยงกับผู้ใช้รายใดรายหนึ่งอย่างชัดเจน ซึ่งจะข้ามตัวเลือกบัญชี Google และหน้าจอขอความยินยอมเมื่อบัญชีได้รับอนุญาตแล้ว
นอกจากนี้ วิธีนี้ยังช่วยป้องกันไม่ให้ผู้ใช้เห็นหน้าจอการเลือกบัญชี 2 หน้าจอที่แตกต่างกัน ได้แก่ หน้าจอการลงชื่อเข้าใช้ของแอปและหน้าจอของ Google Home
หากต้องการทำเช่นนี้ คุณต้องอ้างอิง การตรวจสอบสิทธิ์ผู้ใช้ด้วยการลงชื่อเข้าใช้ด้วย Google และทำตามขั้นตอนต่อไปนี้
สร้างรหัสไคลเอ็นต์ OAuth สำหรับเว็บแอปพลิเคชัน
- เปิดคอนโซล Google Cloud
- ไปที่หน้าข้อมูลเข้าสู่ระบบของคอนโซล Google Cloud
- เลือกโปรเจ็กต์ที่มีอยู่หรือสร้างโปรเจ็กต์ใหม่
- กำหนดค่าหน้าจอขอความยินยอม OAuth (หากยังไม่ได้กำหนดค่า)
- ก่อนสร้างข้อมูลเข้าสู่ระบบ ให้ตรวจสอบว่าหน้าจอขอความยินยอม OAuth ได้รับการกำหนดค่าด้วยรายละเอียดของแอป ซึ่งรวมถึง URL ของนโยบายความเป็นส่วนตัวและข้อกำหนดในการให้บริการ
- สร้างรหัสไคลเอ็นต์ OAuth (ประเภทเว็บแอปพลิเคชัน)
- ในหน้าข้อมูลเข้าสู่ระบบ ให้คลิก
+ CREATE CREDENTIALSและ เลือก รหัสไคลเอ็นต์ OAuth จากเมนูแบบเลื่อนลง - สำหรับประเภทแอปพลิเคชัน ให้เลือกเว็บแอปพลิเคชัน
- ป้อนชื่อสำหรับเว็บไคลเอ็นต์ (เช่น "แบ็กเอนด์เว็บของแอปของฉัน")
- คลิกสร้าง
- ในหน้าข้อมูลเข้าสู่ระบบ ให้คลิก
- ดึงข้อมูลรหัสไคลเอ็นต์
- หลังจากสร้างแล้ว คอนโซลจะแสดงรหัสไคลเอ็นต์ใหม่ ซึ่งเป็นค่าที่คุณจะใช้ในแอปพลิเคชัน Android (เช่น"{project number}-.....apps.googleusercontent.com")
- เราขอแนะนำให้คุณจัดเก็บรหัสไคลเอ็นต์ไว้ภายนอก (เช่น ใน
build.gradle) แทนที่จะฮาร์ดโค้ดโดยตรง
สร้างอินสแตนซ์คำขอ Google Sign-In
ใช้รหัสเว็บแอปเพื่อสร้างคำขอลงชื่อเข้าใช้ Google
// Your Google Cloud console Web Client ID for Google Sign-In
val serverClientId = BuildConfig.DEFAULT_WEB_CLIENT_ID
// Build the request for Google ID token
val googleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(false) // Show all Google Accounts on the device
.setServerClientId(serverClientId) // embed WebClientID in token
.build()
// Build the GetCredentialRequest
val request = GetCredentialRequest.Builder().addCredentialOption(googleIdOption).build()
สร้างโฟลว์การลงชื่อเข้าใช้ด้วย Google
หากต้องการใช้โฟลว์การลงชื่อเข้าใช้ ให้ใช้ CredentialManager เพื่อดำเนินการคำขอ
Sign in with Google เมื่อผู้ใช้เลือกบัญชีแล้ว ให้แยกอีเมลของผู้ใช้จากโทเค็นรหัส Google ที่ได้เพื่อสร้าง android.accounts.Account จากนั้นใช้บัญชีนี้เพื่อเริ่มต้นใช้งานอินสแตนซ์ HomeClient ที่เชื่อมโยงกับผู้ใช้ที่ลงชื่อเข้าใช้รายนั้นโดยเฉพาะ
try {
// CredentialManager is responsible for interacting with various credential providers on the device
val credentialManager = CredentialManager.create(context)
// Credential returns when user has selected an account and the getCredential call completes
val result = credentialManager.getCredential(context = context, request = request)
val credential = result.credential
if (
credential is CustomCredential &&
credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL
) {
try {
val googleCredential = GoogleIdTokenCredential.createFrom(credential.data)
googleCredential.id.let { userEmail ->
Log.i(TAG, "Email found in Google ID Token: $email")
/*
Why "com.google"?
The string "com.google" is a standard identifier used in Android's android.accounts.
Account system to represent accounts managed by Google. This is often used when
interacting with Android's Account Manager or when using Google-specific APIs. So,
even if the email ends in "@gmail.com", the underlying account type or provider is
still considered "com.google" within the Android system.
*/
val account = Account(userEmail, "com.google")
Log.d(TAG,"Switched account to : $userEmail")
// Get the new Home Client Instance with the userEmail
}
Log.i(TAG, "Account switch complete. Emitting navigation event.")
} catch (e: Exception) {
Log.e(TAG,"Could not convert CustomCredential to Google ID Token", e)
}
}
} catch (e: Exception) {
Log.e(TAG, "Google Sign-In failed with unexpected error", e)
}
รับอินสแตนซ์ HomeClient ใหม่
ทำตามขั้นตอนเดียวกันกับที่ระบุไว้ใน
สร้างอินสแตนซ์ Home แต่ให้เรียก
Home.getClient(context, userAccount,
homeConfig)แทนการเรียก
Home.getClient(context, homeConfig)ในขั้นตอนที่ 4
โดยพารามิเตอร์ที่ 2 คือ Lazy<UserAccount> ซึ่งจะแสดงผลอินสแตนซ์
HomeClientWithProvidedAccountซึ่งเป็นคลาสย่อยของ HomeClientที่เชื่อมโยงกับบัญชี Google ที่ระบุอย่างชัดเจน
val client =
Home.getClient(
context = context.applicationContext,
account =
lazy {
// 1. Create the Account object.
val androidAccount = Account(userEmail,
GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE)
// 2. Wrap it in UserAccount.GoogleAccount.
UserAccount.GoogleAccount(androidAccount)
},
homeConfig = HomeConfig()
)
หากผู้ใช้ที่ระบุไม่ได้รับอนุญาต ให้แจ้งให้ผู้ใช้ให้สิทธิ์โดย
เรียกใช้เมธอดต่อไปนี้ใน
HomeClientWithProvidedAccount
อินสแตนซ์:
registerActivityResultCallerForPermissions()พร้อมข้อมูลอ้างอิงไปยัง ActivityResultCaller ที่คุณต้องการใช้requestPermissions()ซึ่งจะแสดงหน้าจอขอความยินยอม GHP ที่ผู้ใช้สามารถให้สิทธิ์ได้
คุณสามารถสร้าง HomeClient ด้วย
UserAccount แล้วเรียก
requestPermissions() ด้วย forceLaunch==true เพื่อเปิดหน้าจอขอความยินยอม
อีกครั้งเพื่อให้ผู้ใช้อัปเดตการให้สิทธิ์ได้
val client =
Home.getClient(
context = context.applicationContext,
account =
lazy {
UserAccount.GoogleAccount(androidAccount)
},
homeConfig = HomeConfig()
)
client.registerActivityResultCallerForPermissions(this)
client.requestPermissions(forceLaunch= true)
ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการสิทธิ์ Home API ได้ที่ API สิทธิ์
รีเฟรชกิจกรรมทั้งหมดด้วย HomeClient ใหม่
เมื่อมีอินสแตนซ์ HomeClient ใหม่แล้ว คุณต้องรีเฟรชกิจกรรมทั้งหมดเพื่อสมัครรับข้อมูลอีกครั้งและดึงข้อมูลโครงสร้าง อุปกรณ์ และข้อมูลอื่นๆ ที่เกี่ยวข้องทั้งหมดที่เชื่อมโยงกับบัญชีผู้ใช้ดังกล่าว
การลงทะเบียนลักษณะและประเภทอุปกรณ์
คลาส FactoryRegistry ช่วยให้นักพัฒนาแอปเพิ่มประสิทธิภาพขนาดไบนารีของแอปได้โดยการระบุลักษณะและประเภทอุปกรณ์ที่แอปใช้โดยชัดแจ้ง
โปรดทราบว่าสิทธิ์และรีจิสทรีของ Factory แยกกัน ดังนั้น ลักษณะและประเภทที่ไม่ได้ลงทะเบียนซึ่งแอปของคุณใช้ได้โดยใช้สิทธิ์ แต่ไม่ได้รวมอยู่ในรีจิสทรีของ Factory จะไม่สามารถเข้าถึงได้โดยใช้ Automation API และจะไม่แสดงผลในการเรียกใช้เมธอด traits() หรือ types() แบบกลุ่ม