API Permissions su Android

Prima di utilizzare una qualsiasi delle API Home per Android, l'app deve avere l'autorizzazione per accedere ai dispositivi nella casa dell'utente, indicata nell'API come struttura. Con l'API Permissions, l'utente può, utilizzando il proprio Account Google, concedere alle app delle API Home l'accesso ai dispositivi della propria casa.

Il flusso di autorizzazioni consente all'utente di creare una struttura, se non è già stata configurata, senza dover utilizzare Google Home app (GHA).

Integra l'API Permissions

Prima di continuare, assicurati di aver seguito la procedura Inizializzare la casa su Android. L'istanza homeManager di questo passaggio viene utilizzata in tutti gli esempi di autorizzazioni qui riportati.

Per prima cosa, registra un ActivityResultCaller con l'SDK. Ad esempio, ecco come viene gestito nell'app di esempio:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    homeManager.registerActivityResultCallerForPermissions(this)
  }

Controlla le autorizzazioni

Prima di richiedere le autorizzazioni, ti consigliamo di verificare se l'utente dell'app ha già concesso il consenso per accedere alla struttura. Per farlo, chiama il hasPermissions() metodo dell'istanza Home per ottenere un Flow di PermissionsState valori:

val permissionsReadyState =
homeManager.hasPermissions().collect { state ->
    when (state) {
      PermissionsState.GRANTED -> println("Permissions granted, no need to request permissions")
      PermissionsState.PERMISSIONS_STATE_UNAVAILABLE ->
          println("Permissions state unavailable, request permissions")

      PermissionsState.NOT_GRANTED ->
          println("OAuth permission is enabled but not granted yet, request permissions")

      PermissionsState.PERMISSIONS_STATE_UNINITIALIZED -> println(
          "Permissions state is not initialized yet. Clients should wait for another status update"
      )
      else ->
          throw IllegalStateException("""
            HomeClient.hasPermissions state should be PermissionsState.GRANTED,
            PermissionState.PERMISSIONS_STATE_UNINITIALIZED, or
            PermissionsState.PERMISSIONS_STATE_UNAVAILABLE. Actual state: $state
          """.trimIndent())
    }
}

Se il controllo restituisce un PermissionsState di NOT_GRANTED o PERMISSIONS_STATE_UNAVAILABLE, significa che l'utente o l'applicazione non ha accesso alla struttura. Se il controllo restituisce un PermissionsState di GRANTED ma una chiamata successiva a structures() non restituisce alcuna struttura, significa che l'utente ha revocato l'accesso all'app tramite la pagina delle impostazioni di GHA oppure che l'utente non dispone dell'accesso richiesto.

Richiedi autorizzazioni

Per accedere alle strutture e ai dispositivi all'interno di una determinata struttura, è necessario concedere l'autorizzazione alla tua app.

Se l'utente non ha ancora concesso le autorizzazioni, utilizza il requestPermissions() metodo dell'istanza Home per avviare l'UI delle autorizzazioni ed elaborare il risultato:

fun requestPermissions(scope: CoroutineScope, onShowSnackbar: (String) -> Unit) {
  scope.launch {
    val result =
      try {
        homeManager.requestPermissions()
      } catch (e: HomeException) {
        PermissionsResult(
          PermissionsResultStatus.ERROR,
          "Got HomeException with error: ${e.message}",
        )
      }
    when (result.status) {
      PermissionsResultStatus.SUCCESS -> {
        Log.i(TAG, "Permissions successfully granted.")
      }
      PermissionsResultStatus.CANCELLED -> {
        Log.i(TAG, "User cancelled Permissions flow.")
        onShowSnackbar("User cancelled Permissions flow")
      }
      else -> {
        Log.e(
          TAG,
          "Failed to grant permissions with error: ${result.status}, ${result.errorMessage}",
        )
        onShowSnackbar("Failed to grant permissions with error: ${result.errorMessage}")
      }
    }
  }
}

Per avviare correttamente l'UI delle autorizzazioni, devi aver già configurato OAuth per la tua app.

Concedi le autorizzazioni

A questo punto dovresti essere in grado di eseguire l'app e consentire a un utente di concedere le autorizzazioni. Il tipo di utenti che possono concedere l'autorizzazione e i tipi di dispositivi per cui è possibile concedere le autorizzazioni variano a seconda che tu abbia registrato la tua app in Google Home Developer Console.

Developer Console la registrazione è obbligatoria per pubblicare un'app utilizzando le API Home. Non è obbligatoria per testare e utilizzare le API Home.

Se un'app non è registrata nella Developer Console, sarà in stato non verificato. Questa opzione è consigliata per testare l'utilizzo delle API Home:

Se un'app è registrata nella Developer Console e è stata approvata per l'accesso a uno o più tipi di dispositivi e la verifica del brand è stata completata per OAuth, sarà in stato verificato. Questo stato è obbligatorio per il lancio di un'app in produzione:

  • I limiti degli utenti di test non si applicano più. Qualsiasi utente può concedere l'autorizzazione all'app.
  • L'utente può concedere l'autorizzazione solo ai tipi di dispositivi approvati in the Developer Console.

Ora che OAuth è configurato, la chiamata dell'app a requestPermissions() attiva le seguenti finestre di dialogo:

  1. All'utente viene chiesto di selezionare l'Account Google che vuole utilizzare.
  2. All'utente viene chiesto di selezionare la struttura a cui vuole concedere l'accesso all'app.
    1. Per un'app non verificata, l'app ha a disposizione tutti i tipi di dispositivi supportati dalle API Home.
    2. Per un'app verificata, l'utente può concedere l'autorizzazione solo ai tipi di dispositivi approvati in Developer Console.
    3. Per i tipi di dispositivi sensibili a cui l'app ha accesso per la gestione, l'utente può limitare l'accesso in base al dispositivo. Ad esempio, se un utente ha tre serrature, può concedere l'accesso a una sola di queste.
  • Consenso OAuth - seleziona account
  • Consenso OAuth - Collega dispositivi 01
  • Consenso OAuth - Collega dispositivo 02
Figura 1: esempio di flusso di consenso OAuth

Una volta concessa l'autorizzazione, l'app può utilizzare le API Home per leggere lo stato e controllare i dispositivi nella struttura. Se l'utente non concede l'autorizzazione all'app per un determinato tipo di dispositivo o dispositivo sensibile, l'app non potrà utilizzare le API Home per accedervi, controllarlo o automatizzarlo.

Modifica autorizzazioni

Per concedere l'autorizzazione ad accedere ai dispositivi in una struttura diversa, è possibile avviare il selettore dell'account per consentire all'utente di scegliere l'Account Google e la struttura a cui passare. Durante questa procedura, all'utente verrà nuovamente mostrata la schermata per il consenso, anche se il consenso è stato concesso in precedenza.

Per farlo, chiama di nuovo requestPermissions() con forcePermissionFlow impostato su ForcePermissionFlow.FORCE_LAUNCH:

homeManager.requestPermissions(forcePermissionFlow = ForcePermissionFlow.FORCE_LAUNCH)

Modifica le autorizzazioni con suggerimenti sulla struttura

I suggerimenti sulla struttura consentono a un'app di preselezionare una struttura specifica o di limitare l'elenco delle strutture disponibili quando si richiede una modifica incrementale delle autorizzazioni delle API Home dell'utente. Se passi i parametri della struttura nella richiesta di autorizzazione, la finestra di dialogo delle autorizzazioni si concentrerà automaticamente sulla struttura scelta, riducendo l'attrito dell'utente ed evitando errori di configurazione.

I suggerimenti sulla struttura vengono gestiti utilizzando la ConsentScreenOptions classe di dati. La classe ConsentScreenOptions accetta i seguenti parametri di configurazione:

  • structureId : l'ID della struttura specifico da preselezionare nella finestra di dialogo delle autorizzazioni. Per ottenerlo, controlla le proprietà della struttura che stai aggiornando.
  • allowedStructureIds : un elenco di ID struttura. Se fornito, la finestra di dialogo delle autorizzazioni filtrerà le strutture disponibili per mostrare solo quelle presenti in questo elenco. Nella maggior parte dei casi, questo parametro può essere lasciato non specificato, a meno che tu non voglia assicurarti che l'utente rimanga all'interno di un elenco di strutture già concesse.
  • allowStructureChange : determina se l'utente è autorizzato a modificare la struttura preselezionata. Nella maggior parte dei casi, imposta questo parametro su true se è specificato almeno uno tra allowedStructureIds e structureId per supportare il comportamento naturale dell'utente.

Passa questo oggetto come parametro facoltativo nella chiamata requestPermissions(), con forcePermissionFlow impostato su ForcePermissionFlow.FORCE_LAUNCH:

import com.google.home.ConsentScreenOptions

// Create the ConsentScreenOptions class, allowing structure changes while
// ensuring the permissions dialog pre-selects the target structure on launch
val consentOptions = ConsentScreenOptions(
    structureId = target-structure-id,
    allowStructureChange = true
)

homeManager.requestPermissions(forcePermissionFlow = ForcePermissionFlow.FORCE_LAUNCH, consentScreenOptions = consentOptions)

All'utente verrà mostrata la schermata per il consenso già filtrata in base alla struttura indicata nell'oggetto ConsentScreenOptions.

Consenti all'utente di cambiare struttura con i suggerimenti sulla struttura

Se un utente ha più strutture in un'app e vuoi preselezionarne una, consentendogli comunque di passare da una struttura all'altra, attiva le modifiche della struttura con il flag allowStructureChange e fornisci un elenco di strutture in allowedStructureIds:

val consentOptions = ConsentScreenOptions(
    structureId = target-structure-id,
    allowedStructureIds = listOf(target-structure-id, another-structure-id),
    allowStructureChange = true
)

Revoca autorizzazioni

Gli utenti possono revocare l'accesso concesso in precedenza:

  1. Tramite la pagina I miei account Google > Dati e privacy > App e servizi di terze parti. In questo modo verrà revocato il token OAuth rilasciato al momento della concessione iniziale del consenso e verrà revocato l'accesso a qualsiasi istanza dell'app utilizzata dall'utente su tutte le piattaforme (smartphone) e le strutture.

    L'utente potrebbe essere indirizzato con un deep link alla pagina secondaria App e servizi di terze parti utilizzando il seguente schema URL:

    https://myaccount.google.com/connections/link?project_number=Cloud project_number
    
  2. Tramite la pagina GHA > Impostazioni > App collegate. Se fai clic su in GHA, viene visualizzata la pagina Impostazioni. Da qui, fai clic sul riquadro App collegate per accedere a una pagina simile alla schermata per il consenso. Da questa pagina l'utente può rimuovere l'accesso all'app. L'utente può utilizzare la stessa pagina per modificare i tipi di dispositivi o i dispositivi sensibili specifici accessibili all'app.

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 ad 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
            }
        }
    }
}

Autorizzazioni Ok Google

Il okGoogle comando è un comando a livello di dispositivo e può essere utilizzato per automatizzare qualsiasi dispositivo nella struttura. Tuttavia, un'app delle API Home potrebbe non avere accesso a tutti i dispositivi. La seguente tabella descrive come vengono applicate le autorizzazioni in questi casi.

Automazione Caratteristica Applicazione delle autorizzazioni
Alle 22:00, trasmetti "È ora di andare a dormire" sullo speaker della camera da letto. AssistantBroadcastTrait sul dispositivo. Creazione dell'automazione:
  • Il dispositivo di trasmissione deve essere un dispositivo con Assistente.
  • L'app e l'utente devono avere accesso al dispositivo su cui viene eseguita la trasmissione.
Esecuzione dell'automazione:
  • L'app e l'utente devono avere accesso al dispositivo su cui viene eseguita la trasmissione.
Alle 22:00, trasmetti "È ora di andare a dormire" su tutti i dispositivi AssistantBroadcastTrait sulla struttura. Creazione dell'automazione:
  • Nella struttura deve essere presente almeno un dispositivo con Assistente a cui l'app e l'utente hanno accesso.
  • L'app e l'utente devono avere accesso alla struttura.
Esecuzione dell'automazione:
  • L'app e l'utente devono avere accesso alla struttura.
Alle 22:00, "Fammi sentire un po' di musica" AssistantFulfillmentTrait.OkGoogleCommand Creazione dell'automazione:
  • L'app e l'utente devono avere accesso ai dispositivi a cui l'automazione invia i comandi.
Esecuzione dell'automazione:
  • L'app e l'utente devono avere accesso ai dispositivi a cui la l'automazione invia i comandi.
Ogni volta che qualcuno dice "Fammi sentire un po' di musica" VoiceStarterTrait.OkGoogleEvent Creazione dell'automazione:
  • L'app e l'utente devono avere accesso alla struttura. Un'automazione non richiede un dispositivo con Assistente per superare la convalida o per essere eseguita, perché qualsiasi utente con accesso alla struttura può utilizzare il proprio smartphone (utilizzando lo stesso Account Google) per interagire con l'Assistente e attivare VoiceStarter.
Esecuzione dell'automazione:
  • L'app non richiede l'autorizzazione per accedere al dispositivo che avvia l'automazione.
  • L'app e l'utente devono avere l'autorizzazione per accedere al dispositivo su cui viene eseguita l'azione.

Indicazioni se l'utente revoca tutte le autorizzazioni

Se l'utente revoca tutte le autorizzazioni, tutte le automazioni esistenti smetteranno di funzionare. Inoltre, se l'utente revoca l'accesso a dispositivi specifici, gli starter, le condizioni e le azioni associate a questi dispositivi smetteranno di funzionare.

Ogni volta che l'app viene avviata, assicurati che le autorizzazioni siano ancora attive. Se sono state revocate, assicurati che tutti i dati precedenti, inclusi quelli memorizzati nella cache dell'applicazione, vengano rimossi.

Quando l'accesso alla struttura viene revocato, a StructureAccessRevokedEvent viene inviato al tuo backend cloud. Consulta la sezione Concessioni di strutture per il flusso di lavoro di revoca end-to-end dell'app mobile e del cloud del partner.