Dostęp do interfejsów Structure API można uzyskać za pomocą interfejsów Home API na Androidzie. Zaimportuj te pakiety do swojej aplikacji:
import com.google.home.Home
import com.google.home.Id
import com.google.home.Structure
Obsługa błędów
Każda metoda w interfejsach Home API może zgłosić wyjątek
HomeException, dlatego zalecamy używanie bloku try-catch do
przechwytywania HomeException we wszystkich wywołaniach.
Podczas obsługi HomeException sprawdź pola
error.code i
error.message, aby dowiedzieć się, co poszło nie tak. Mogą też występować kody błędów podrzędnych
as well, dlatego wywołaj metodę
getSubErrorCodes() i sprawdź wynik.
Wszystkie nieobsłużone wyjątki spowodują awarię aplikacji.
Więcej informacji znajdziesz w sekcji Obsługa błędów.
Przykładowe wywołania
Pobieranie listy struktur
Po zainicjowaniu wywołanie structures() zwraca strumień struktur, do których masz dostęp:
// Get a flow of all structures accessible to the user val allStructuresFlow: HomeObjectsFlow<Structure> = home.structures() // Calling list() on a HomeObjectsFlow returns the first Set of elements. val allStructures: Set<Structure> = allStructuresFlow.list()
Interfejs structures() API to strumień, który może nie zwrócić od razu prawidłowej listy struktur. Jeśli Twoja aplikacja jest reaktywna i subskrybuje ten strumień, aby sterować interfejsem, powinna w końcu otrzymać prawidłową listę struktur.
Mogą też wystąpić inne sytuacje, w których zwracana jest pusta lista struktur, np. gdy telefon użytkownika utraci połączenie lub gdy użytkownik cofnie uprawnienia Twojej aplikacji. Musisz zadbać o obsługę tych przypadków w swojej aplikacji.
Jeśli zamiast programowania reaktywnego zdecydowanie preferujesz programowanie imperatywne, możesz użyć operatora strumienia terminala:
val everyStructure = withTimeout(5000) { home.structures().first { it.isNotEmpty() } }
To wywołanie czeka na prawidłową listę struktur, która ma się pojawić w strumieniu, i przekracza limit czasu, jeśli lista nie zostanie odebrana w określonym przez aplikację limicie czasu.
Pobieranie właściwości struktury
Gdy masz listę struktur, możesz uzyskać dostęp do ich właściwości:
// Get a flow on a structure. Flow emits new values on structure metadata changes: name. val structureFlow: Flow<Structure> = home.structures().itemFlow(myStructureId) // Get a snapshot of the structure. val structure: Structure = structureFlow.first() // Get structure properties println("id ${structure.id}") println("name ${structure.name}")
Znajdowanie struktury według nazwy
Jeśli znasz nazwę struktury, możesz też uzyskać do niej dostęp za pomocą właściwości name:
val myHome = home.structures().list().first { it.name == "My home" }
Stamtąd można uzyskać dostęp do właściwości, pomieszczeń i urządzeń każdej struktury.
Praca z wieloma strukturami
Aby używać więcej niż 1 struktury, uzyskaj osobne odniesienie do każdej z nich:
var structure1: Structure? = null var structure2: Structure? = null try { structure1 = home.structures().list().firstOrNull { it.name == "Main House" } } catch (e: HomeException) { // Code for handling the exception } try { structure2 = home.structures().list().firstOrNull { it.name == "Guest Cottage" } } catch (e: HomeException) { // Code for handling the exception }
Pobieranie listy pomieszczeń
Gdy masz strukturę, możesz pobrać listę pomieszczeń i uzyskać dostęp do ich właściwości:
val allRoomsFlow: HomeObjectsFlow<Room> = structure.rooms() val allRooms: Set<Room> = allRoomsFlow.list() val room: Room = allRooms.first() println("id ${room.id}") println("name ${room.name}")
Tworzenie pomieszczenia
Aby utworzyć nowe pomieszczenie:
val testName = "Test Room Name" val newRoom: Room = structure.createRoom(testName)
Usuwanie pomieszczenia
Możesz też usunąć pomieszczenie:
val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull() structure.deleteRoom(roomToDelete!!)
Możesz też usunąć pomieszczenie, podając tylko jego identyfikator:
val roomToDelete1 = allRooms.filter { it.id == testRoomId }.firstOrNull() structure.deleteRoom(roomToDelete1!!)
Jeśli usuniesz pomieszczenie z urządzeniami, urządzenia nadal będą w strukturze, ale nie będą już przypisane do pomieszczenia.
Przenoszenie urządzeń do innego pomieszczenia
Gdy masz strukturę, możesz przenieść urządzenia do innego pomieszczenia w tej strukturze:
val room2 = structure.rooms().get(Id("room_id_other_structure")) val device1 = structure.devices().get(Id("device_id1")) structure.moveDevicesToRoom(room2!!, listOf(device1!!))
Jeśli masz tylko identyfikatory urządzeń i pomieszczeń, możesz też przenieść urządzenia:
structure.moveDevicesToRoom(Id("room_id_other_structure"), listOf(Id("device_id1")))
Zmienianie nazwy pomieszczenia
Aby zmienić nazwę pomieszczenia, wywołaj metodę setName():
livingRoom.setName("Living Room")
Nazwy zostaną obcięte, jeśli przekroczą limit 60 punktów kodowych Unicode (znaków), i nie zostaną zgłoszone żadne błędy. Deweloperzy są odpowiedzialni za obsługę długich nazw i mogą na przykład zdecydować, czy chcą informować użytkowników, że nazwy zostaną obcięte.
Wyświetlanie typów urządzeń, do których użytkownik przyznał uprawnienia
W ekosystemie Google Home użytkownicy mogą przyznawać uprawnienia do wszystkich urządzeń danego typu naraz. W przypadku typów urządzeń, które wymagają szczególnej ochrony lub są objęte ograniczeniami, takich jak zamki, kamery czy dzwonki do drzwi, użytkownicy muszą przyznać uprawnienia do każdego z nich osobno.
Aby sprawdzić, czy użytkownik przyznał uprawnienia do dostępu do typu urządzenia, które wymaga szczególnej ochrony lub jest objęte ograniczeniami, użyj funkcji consentedDeviceTypes() na poziomie struktury:
import com.google.home.Structure
import com.google.home.DeviceType
import com.google.home.DeviceTypeFactory
import com.google.home.consentedDeviceTypes // Extension function from the SDK
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
/**
* Example of how an app may monitor which device types have been granted access by a user.
*/
fun monitorDeviceConsent(structure: Structure, myScope: CoroutineScope) {
// Obtain the flow of consented device type factories
val consentedTypesFlow: Flow<Set<DeviceTypeFactory<out DeviceType>>> =
structure.consentedDeviceTypes()
myScope.launch {
consentedTypesFlow.collect { consentedSet ->
// Check if the user has consented to share a specific restricted
// type, such as a Doorbell or Camera.
val hasCameraAccess = consentedSet.any {
it.toString() == "matter.google.type.GoogleDoorbellDevice"
}
if (hasCameraAccess) {
// Enable features that require camera access
} else {
// Inform the user or disable camera-specific features
}
}
}
}
Automatyzacja
Punktem wejścia do interfejsu Automation API jest struktura. Więcej informacji o automatyzacji w interfejsach Home API znajdziesz w artykule Omówienie interfejsu Automation API na Androidzie.