È possibile accedere alle API Structure tramite le API Home per Android. Importa questi pacchetti nella tua app:
import com.google.home.Home
import com.google.home.Id
import com.google.home.Structure
Gestione degli errori
Qualsiasi metodo nelle API Home può generare un errore
HomeException, pertanto ti consigliamo di utilizzare un blocco try-catch per
intercettare HomeException in tutte le chiamate.
Quando gestisci HomeException, controlla i campi
error.code e
error.message per scoprire cosa è andato storto. Potrebbero essere presenti anche codici di errore secondari, quindi chiama il metodo
getSubErrorCodes() e controlla il risultato.
Qualsiasi eccezione non gestita causerà l'arresto anomalo dell'app.
Per saperne di più, consulta Gestione degli errori.
Chiamate di esempio
Recuperare un elenco di strutture
Una volta inizializzata, una chiamata structures() restituisce un flusso di strutture
accessibili:
// 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()
L'API structures() è un flusso che potrebbe non restituire immediatamente un elenco valido di strutture. Se la tua app è reattiva e si iscrive a questo flusso per
gestire la UI, alla fine dovrebbe essere restituito un elenco valido di strutture.
Esistono altre situazioni in cui potrebbe essere restituito un elenco di strutture vuoto, ad esempio se lo smartphone dell'utente perde la connettività o se l'utente ha revocato le autorizzazioni alla tua app. Devi assicurarti di gestire questi casi nella tua app.
In alternativa, se è necessario utilizzare la programmazione imperativa anziché quella reattiva, è possibile utilizzare un operatore di flusso terminale:
val everyStructure = withTimeout(5000) { home.structures().first { it.isNotEmpty() } }
Questa chiamata attende che un elenco valido di strutture venga inviato tramite il flusso e scade se l'elenco non viene ricevuto entro il timeout designato dall'app.
Recupero delle proprietà della struttura
Con l'elenco delle strutture a portata di mano, puoi accedere alle relative proprietà:
// 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}")
Trovare una struttura in base al nome
Se conosci il nome di una struttura, puoi accedervi anche utilizzando la proprietà name:
val myHome = home.structures().list().first { it.name == "My home" }
Da qui è possibile accedere a proprietà, stanze e dispositivi per ogni struttura.
Lavorare con più strutture
Per utilizzare più di una struttura, ottieni un riferimento separato per ciascuna:
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 }
Ottenere un elenco di stanze
Con una struttura a portata di mano, puoi ottenere un elenco di stanze e accedere alle relative proprietà:
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}")
Crea una stanza virtuale
Per creare una nuova stanza:
val testName = "Test Room Name" val newRoom: Room = structure.createRoom(testName)
Eliminare una stanza
In alternativa, puoi eliminare una stanza:
val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull() structure.deleteRoom(roomToDelete!!)
Puoi anche eliminare una stanza solo con un ID:
val roomToDelete1 = allRooms.filter { it.id == testRoomId }.firstOrNull() structure.deleteRoom(roomToDelete1!!)
Se viene eliminata una stanza con dispositivi, questi rimarranno nella struttura ma non saranno più assegnati a una stanza.
Spostare i dispositivi in un'altra stanza
Una volta creata una struttura, puoi spostare i dispositivi in un'altra stanza all'interno di quella struttura:
val room2 = structure.rooms().get(Id("room_id_other_structure")) val device1 = structure.devices().get(Id("device_id1")) structure.moveDevicesToRoom(room2!!, listOf(device1!!))
Se hai solo gli ID dispositivo e stanza, puoi anche spostare i dispositivi:
structure.moveDevicesToRoom(Id("room_id_other_structure"), listOf(Id("device_id1")))
Modificare il nome di una stanza
Chiama il metodo setName()
per modificare il nome di una stanza:
livingRoom.setName("Living Room")
I nomi verranno troncati se superano il limite di 60 punti di codice Unicode (caratteri) e non verranno generati errori. Gli sviluppatori sono responsabili della gestione dei nomi lunghi e, ad esempio, possono decidere se informare gli utenti che i nomi verranno troncati.
Visualizzare i tipi di dispositivi per cui un utente ha concesso le autorizzazioni
Nell'ecosistema Google Home, per la maggior parte dei tipi di dispositivi, gli utenti possono concedere le autorizzazioni per tutti i dispositivi di quel tipo contemporaneamente. Per i tipi di dispositivi sensibili o con limitazioni, come serrature, videocamere o campanelli, gli utenti devono concedere l'autorizzazione singolarmente.
Per determinare se un utente ha concesso l'autorizzazione per accedere a un tipo di dispositivo sensibile o
con limitazioni, utilizza la funzione consentedDeviceTypes() a livello di struttura:
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
}
}
}
}
Automazioni
Il punto di accesso all'API Automation avviene tramite una struttura. Per saperne di più sulle automazioni nelle API Home, consulta la panoramica dell'API Automation su Android.