1. Te damos la bienvenida
Matter, creado con el objetivo de unificar los estándares de IoT, conecta dispositivos de casa inteligente en varios ecosistemas, como Google Home, Zigbee, la malla Bluetooth, Z‐Wave y muchos más.
Los dispositivos móviles son un punto de interacción central con los dispositivos de casa inteligente. Si desea compilar sus propias aplicaciones para Android compatibles con dispositivos Matter, podemos ayudarlo a comenzar rápidamente.
La app de ejemplo de Google Home para Matter (GHSA for Matter) muestra las API del SDK de Home para dispositivos móviles, lo que permite a los usuarios encargar y compartir dispositivos. También puedes usar la app de ejemplo como herramienta de aprendizaje para comprender mejor los conceptos clave de Matter, así como una herramienta para depurar y solucionar problemas de interacción con dispositivos Matter.
Actividades
En este Codelab, descargarás el código fuente de la app de ejemplo y aprenderás a usar el SDK de Home para dispositivos móviles a fin de encargar y compartir dispositivos. También aprenderás a usar las bibliotecas de asignación y agrupamiento en clústeres del repositorio de Matter (connectedhomeip
).
Después de descargar la app de ejemplo, revisaremos el código fuente en Android Studio y, luego, implementaremos las siguientes API del SDK de Home para dispositivos móviles:
También obtendrás más información sobre los conceptos de asignación, las telas de Matter y cómo controlar los dispositivos Matter.
Requisitos
Antes de comenzar, asegúrate de completar los siguientes pasos:
- Consulta la Guía de Google Home de ejemplo para Matter.
- Descarga Android Studio.
- Tener un dispositivo con Android O (8.1, API nivel 27) o versiones posteriores disponible para pruebas Para asegurarte de que tu dispositivo tenga la asistencia más reciente de Matter, consulta la guía Cómo verificar los módulos y servicios de Matter.
- Compila un dispositivo Matter con funciones de encendido y apagado. Esta app de ejemplo funciona con un dispositivo virtual y un ESP32.
- Crea un dispositivo virtual de Matter con la app de
rootnode_dimmablelight_bCwGYSDpoe
. Cuando crees una integración de Matter en Home Developer Console, usa0xFFF1
como ID de proveedor y0x8000
como ID de producto. - Compila un dispositivo Espressif con el
all-clusters-app
. Cuando crees una integración de Matter en Google Developer Console, usa0xFFF1
como ID de proveedor y0x8001
como ID de producto.
- Crea un dispositivo virtual de Matter con la app de
- Consulta cómo configurar los Servicios de Google Play.
No necesitas un concentrador, por ejemplo, un Google Nest Hub (2a generación), para encargar y controlar dispositivos con la app de ejemplo.
2. Prepárate
El repositorio de GitHub de la app de muestra incluye bibliotecas de terceros del repositorio de Matter (connectedhomeip
). Estas bibliotecas nativas superan los 50 MB y requieren el uso de Git File Storage (LFS).
La app de inicio del codelab se encuentra en la rama codelab
. Para comenzar a trabajar con el código fuente del codelab, puedes descargar el archivo ZIP. Este ZIP incluye las bibliotecas nativas del SDK de Matter sin la necesidad de Git LFS:
Usarás este archivo ZIP codelab
para compilar una muestra que funcione.
Versiones de Codelab
La rama codelab
está etiquetada con la versión 1.2.2 de la app de muestra. Para comparar las actualizaciones mientras trabajas en cada paso, descarga el código fuente completo de esta versión.
Si deseas clonar el repositorio de GitHub, sigue las instrucciones en el archivo README de la app de muestra.
Dependencias
Te guiaremos a través del código fuente que se requiere para compartir y poner en marcha los dispositivos, pero es posible que tengas en cuenta las siguientes dependencias antes de comenzar:
- SDK de Home Mobile.
implementation 'com.google.android.gms:play-services-home:16.0.0'
- Bibliotecas del SDK de Matter.
// Native libs implementation fileTree(dir: "third_party/connectedhomeip/libs", include: ["*.jar", "*.so"])
- Material Design Para obtener más información, consulta MDC-103 para Android: Temas de Material con color, elevación y tipo (Kotlin) y Material Theme Builder.
implementation 'com.google.android.material:material:1.5.0'
- Proto Datastore, usado para conservar los datos de las apps Los repositorios y los serializadores de Datastore se almacenan en
java/data
, incluidos los esquemas para los dispositivos y las preferencias del usuario. Para obtener más información sobre DataStore, consulta Cómo trabajar con Proto Datastore.implementation "androidx.datastore:datastore:$dataStoreVersion" implementation 'androidx.datastore:datastore-core:1.0.0' implementation 'com.google.protobuf:protobuf-javalite:3.18.0'
- Hilt para conservar los datos y admitir la inserción de dependencias
kapt 'com.google.dagger:hilt-compiler:2.41' implementation 'com.google.dagger:hilt-android:2.41'
Código fuente
Ya se creó la interfaz de usuario y la mayor parte de la funcionalidad para usted.
En este codelab, agregaremos la funcionalidad de Matter para los siguientes archivos:
java/commissioning/AppCommissioningService
: Te permite asignar dispositivos a la estructura de desarrollo.java/screens/HomeFragment
yjava/screens/HomeViewModel.kt
: Incluyen la funcionalidad de puesta en marcha del SDK de Home para dispositivos móviles.java/screens/DeviceViewModel
: Incluye las llamadas a la API de Compartir dispositivo
Cada archivo se comenta con el bloque de código que modificarás, por ejemplo:
// CODELAB: add commissioningFunction()
De esta manera, podrás encontrar rápidamente la sección correspondiente del codelab.
3. Comisión ante Google
Para poder controlar los dispositivos y permitirles comunicarse entre sí dentro de la misma estructura, es necesario que los comisione un encargado, que en este caso es esta aplicación de muestra, la app de ejemplo de Google Home para Matter.
Es importante comprender los siguientes conceptos sobre la asignación de asuntos:
- Las telas permiten que los dispositivos se comuniquen entre sí.
- Las fábricas mantienen un conjunto compartido de credenciales únicas.
- Los ecosistemas son responsables de emitir certificados raíz de confianza, asignar ID de tejido y asignar ID de nodos únicos. Un ecosistema es el servicio de backend de un comisionado, por ejemplo, el Home Graph para el ecosistema de Google Home.
- Los dispositivos se pueden asignar a más de una estructura (función de administrador múltiple).
Para poner en marcha un dispositivo, deberás usar la API de CommissioningClient. Una llamada a .commissionDevice()
muestra un IntentSender, que inicia la actividad adecuada en los Servicios de Google Play:
interface CommissioningClient { Task<IntentSender> commissionDevice(CommissioningRequest request); }
En las siguientes secciones, veremos el mínimo código necesario para encargar los dispositivos a la estructura de Google.
Paso 1: selector de actividades
Para controlar IntentSender
desde CommissioningClient
, puedes usar un ActivityResultLauncher:
private lateinit var commissioningLauncher: ActivityResultLauncher<IntentSenderRequest>
commissioningLauncher = registerForActivityResult( StartIntentSenderForResult() ) { result: ActivityResult -> if (result.resultCode == RESULT_OK) { Timber.d(TAG, "Commissioning succeeded.") } else { Timber.d(TAG, "Commissioning failed. " + result.resultCode) } }
Paso 2: función de puesta en marcha
Aquí tienes un ejemplo básico que usa la API de CommissioningClient para encargar un dispositivo a la estructura de Google.
- El proceso de puesta en marcha comienza con la función
commissionDevice()
. Primero, se define unCommissioningRequest
. Con esta configuración predeterminada, los dispositivos se encargan solo a la estructura local de Android. Matter
es el punto de entrada del SDK de Home Mobile. En la próxima llamada,.getCommissioningClient
obtiene un objeto CommissioningClient dethis
(actividad)..commissionDevice()
aceptaCommissioningRequest
.- Por último, se llama a
.addOnSuccessListener
para procesarCommissioningResult
e iniciar la actividad del dispositivo de comisión de Servicios de Google Play (GPS).
private fun commissionDevice() { val request: CommissioningRequest = CommissioningRequest.builder().build() Matter.getCommissioningClient(this) .commissionDevice(request) .addOnSuccessListener { result -> commissioningLauncher.launch(IntentSenderRequest.Builder(result).build()) } }
Aprovecha Android Fabric local a través de la configuración de Android para simplificar el proceso de puesta en marcha sus dispositivos con otras telas.
A continuación, aprenderás cómo encargar un dispositivo a una estructura de desarrollo.
Para obtener una descripción general de la interfaz de usuario durante el proceso de asignación, consulte la Guía de ejemplo de la aplicación de Google Home para Matter.
4. Comisión a una estructura de desarrollo
Los dispositivos se pueden asignar a más de una tela. Para administrar las vinculaciones de confianza, los dispositivos almacenan un FabricTable
que contiene varios miembros de FabricInfo
, por ejemplo:
- Identificación de Fabric
- ID de nodo asignado por la estructura al dispositivo
- ID del proveedor
- ID de Fabric
- Credenciales operativas del dispositivo
El administrador de dominio administrativo (ADM) define las credenciales de tejido. En la situación anterior, los Servicios de Google Play son el ecosistema que actúa como autoridad certificada (CA) raíz de confianza. Cuando encargas los dispositivos a la estructura de Android local, cada dispositivo incluye el mismo conjunto de credenciales de fábrica y el mismo conjunto de CA.
Servicios de comisionados personalizados
A fin de encargar la estructura de Android local, usamos los parámetros predeterminados para compilar CommissioningRequest
en la API de CommissioningClient:
val request: CommissioningRequest = CommissioningRequest.builder().build()
Si quieres controlar y administrar dispositivos nuevos desde tu app, debes crear una estructura de desarrollo local y obtener las credenciales operativas para asignar los dispositivos. En este caso, tu app se convierte en un ecosistema independiente y único que asigna a los dispositivos las credenciales de nodo adecuadas.
Puedes informar al SDK de Home Mobile que quieres encargar dispositivos a tu propia red. Para ello, pasa un servicio personalizado a CommissioningRequest:
class CommissioningRequest { static CommissioningRequest.Builder builder(); class Builder { Builder setCommissioningService(@Nullable ComponentName commissioningService); CommissioningRequest build(); } }
En los siguientes pasos, modificaremos la función commissionDevice()
para usar un servicio personalizado. También agregaremos un Launcher de actividad al fragmento de la página principal y usaremos objetos LiveData para administrar el flujo de API.
Paso 1: Crea un selector de actividad GPS
Primero, creemos un Launcher de actividad para controlar el IntentSender
desde la API de CommissioningClient.
- Abre
HomeFragment
en la carpetajava/screens/home/
. - Reemplaza el comentario
// CODELAB: commissionDeviceLauncher declaration
por la siguiente declaración:// The ActivityResult launcher that launches the "commissionDevice" activity in Google Play // Services. private lateinit var commissionDeviceLauncher: ActivityResultLauncher<IntentSenderRequest>
- Reemplaza el comentario
// CODELAB: commissionDeviceLauncher definition
por el siguiente código para registrar y controlar el resultado de la actividad de puesta en marcha:commissionDeviceLauncher = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result -> // Commission Device Step 5. // The Commission Device activity in GPS has completed. val resultCode = result.resultCode if (resultCode == Activity.RESULT_OK) { Timber.d("CommissionDevice: Success") // We now need to capture the device information for the app's fabric. // Once this completes, a call is made to the viewModel to persist the information // about that device in the app. showNewDeviceAlertDialog(result) } else { viewModel.commissionDeviceFailed(resultCode) } } ```
Paso 2: Crea objetos LiveData
La devolución de llamada exitosa de la API de .commissionDevice()
proporciona el IntentSender
que se usará para iniciar la actividad del dispositivo de comisión en los Servicios de Google Play. En el HomeViewModel
, crearemos dos objetos LiveData para informar sobre el resultado de esta llamada a la API:
commissionDeviceStatus
para realizar un seguimiento deTaskStatus
.commissionDeviceIntentSender
para controlar el resultado de la llamada a.commissionDevice()
. Este objeto LiveData iniciará elActivityLauncher
que acabamos de crear y mostrará la actividad del dispositivo de la comisión de GPS al usuario.
- En
private fun setupObservers()
, reemplaza el comentario// CODELAB: commissionDeviceStatus
por el siguiente observador:// The current status of the share device action. viewModel.commissionDeviceStatus.observe(viewLifecycleOwner) { status -> Timber.d("commissionDeviceStatus.observe: status [${status}]") }
- A continuación, reemplaza el comentario
// CODELAB: commissionDeviceIntentSender
por el siguiente observador:viewModel.commissionDeviceIntentSender.observe(viewLifecycleOwner) { sender -> Timber.d( "commissionDeviceIntentSender.observe is called with [${intentSenderToString(sender)}]") if (sender != null) { // Commission Device Step 4: Launch the activity described in the IntentSender that // was returned in Step 3 (where the viewModel calls the GPS API to commission // the device). Timber.d("CommissionDevice: Launch GPS activity to commission device") commissionDeviceLauncher.launch(IntentSenderRequest.Builder(sender).build()) viewModel.consumeCommissionDeviceIntentSender() } }
Paso 3: Llama a la API
Ahora que escribimos el código para manejar el flujo de API, es momento de llamar a la API, pasar un servicio personalizado (que definiremos en el siguiente paso) y publicar en nuestros objetos LiveData.
- Abre
HomeViewModel.kt
en la carpetajava/screens/home/
. - Reemplaza el comentario
// CODELAB: commissionDevice
por la siguientecommissionDeviceRequest
.setCommissioningService
vinculaAppCommissioningService
a una instanciaCommissioningService
, que se muestra en una función de devolución de llamada. Cuando pases un servicio personalizado, el SDK de Home para dispositivos móviles primero encargará los dispositivos a la estructura de Google y, luego, enviará la carga útil de integración aAppCommissioningService
.fun commissionDevice(context: Context) { _commissionDeviceStatus.postValue(TaskStatus.InProgress) val commissionDeviceRequest = CommissioningRequest.builder() .setCommissioningService(ComponentName(context, AppCommissioningService::class.java)) .build()
- Llama a
.getCommissioningClient()
y, luego, llama a.commissionDevice()
.Matter.getCommissioningClient(context) .commissionDevice(commissionDeviceRequest)
Para completar nuestra función commissionDevice
, agrega addOnSuccessListener
y addOnFailureListener
, y publica en los objetos LiveData:
.addOnSuccessListener { result -> // Communication with fragment is via livedata _commissionDeviceIntentSender.postValue(result) } .addOnFailureListener { error -> Timber.e(error) _commissionDeviceStatus.postValue( TaskStatus.Failed("Failed to to get the IntentSender.", error) } }
Después de usar el remitente, se debe llamar a consumeCommissionDeviceIntentSender()
para evitar recibirlo de nuevo después de un cambio de configuración.
/** * Consumes the value in [_commissionDeviceIntentSender] and sets it back to null. Needs to be * called to avoid re-processing the IntentSender after a configuration change (where the LiveData * is re-posted). */ fun consumeCommissionDeviceIntentSender() { _commissionDeviceIntentSender.postValue(null) }
5. Crear un objeto Service de comisión
En la función commissionDevice()
, solicitamos obtener un CommissioningService de la API de CommissioningClient. En este flujo, la API de CommissioningClient encarga primero los dispositivos a la estructura local de Android y, luego, muestra una devolución de llamada que incluye el objeto CommissioningRequestMetadata:
public interface CommissioningService { interface Callback { void onCommissioningRequested(CommissioningRequestMetadata metadata); } }
Ahora, heredaremos CommissioningService.Callback y proporcione la funcionalidad necesaria para encargar los dispositivos a nuestra app de muestra. A continuación, se muestra un ejemplo de una implementación básica de CommissioningService:
class MatterCommissioningService : Service(), CommissioningService.Callback { private val commissioningServiceDelegate = CommissioningService.Builder(this) .setCallback(this) .build() override fun onBind(intent: Intent) = commissioningServiceDelegate.asBinder() override fun onCommissioningRequested(metadata: CommissioningRequestMetadata) { // perform commissioning commissioningServiceDelegate .sendCommissioningComplete(CommissioningCompleteMetadata.builder().build()) } }
Paso 1: Explora el AppCommissioningService personalizado
A fin de ayudarte a comenzar, ya definimos la estructura de clase básica para nuestro objeto Service de comisión personalizado. A continuación, se incluye una breve descripción general de la funcionalidad del servicio. Para continuar, abre AppCommissioningService
en java/commissioning
.
Agregamos las siguientes importaciones para las API del SDK de Home para dispositivos móviles:
import com.google.android.gms.home.matter.commissioning.CommissioningCompleteMetadata import com.google.android.gms.home.matter.commissioning.CommissioningRequestMetadata import com.google.android.gms.home.matter.commissioning.CommissioningService
AppCommissioningService
también incluye bibliotecas del repositorio de Matter (connectedhomeip
):
import com.google.home_sample_app_for_matter.chip.ChipClient
Por último, el servicio incluye importaciones para admitir corrutinas de Hilt y Kotlin.
A continuación, creamos el constructor y configuramos algunos elementos, incluido el commissioningServiceDelegate
, que usaremos para informarle a los Servicios de Google Play cuando se complete la puesta en marcha.
private lateinit var commissioningServiceDelegate: CommissioningService ... commissioningServiceDelegate = CommissioningService.Builder(this).setCallback(this).build()
Ahora es momento de agregar las funciones de puesta en marcha.
Paso 2: Anula onCommissioningRequest
Para asignar dispositivos a la estructura de desarrollo de la app, completa los siguientes pasos:
- Abre
AppCommissioningService
enjava/commissioning
. - Ubica la función
onCommissioningRequested()
. Proporcionamos un mensaje de registro que imprime elCommissioningRequestMetadata
. Reemplaza el comentario// CODELAB: onCommissioningRequested()
para iniciar la corrutinaserviceScope
y obtener ladeviceId
.// Perform commissioning on custom fabric for the sample app. serviceScope.launch { val deviceId = devicesRepository.incrementAndReturnLastDeviceId()
- Realizar la asignación Para este paso, podemos pasar la información del dispositivo que se muestra en el objeto CommissioningRequestMetadata. La
ChipClient
usa esta información de metadatos para crear un canal seguro entre la app de GHSA para Matter y tu dispositivo.Timber.d("Commissioning: App fabric -> ChipClient.establishPaseConnection(): deviceId [${deviceId}]") chipClient.awaitEstablishPaseConnection( deviceId, metadata.networkLocation.ipAddress.hostAddress!!, metadata.networkLocation.port, metadata.passcode) Timber.d("Commissioning: App fabric -> ChipClient.commissionDevice(): deviceId [${deviceId}]") chipClient.awaitCommissionDevice(deviceId, null)
- Usa
commissioningServiceDelegate
para informar a los Servicios de Google Play que se completó la asignación. En.sendCommissioningComplete()
, pasa CommissioningCompleteMetadata.Timber.d("Commissioning: Calling commissioningServiceDelegate.sendCommissioningComplete()") commissioningServiceDelegate .sendCommissioningComplete( CommissioningCompleteMetadata.builder().setToken(deviceId.toString()).build()) .addOnSuccessListener { Timber.d("Commissioning: OnSuccess for commissioningServiceDelegate.sendCommissioningComplete()") } .addOnFailureListener { ex -> Timber.e(ex, "Commissioning: Failed to send commissioning complete.", ex) } }
Ejecuta la app
Ahora que todo el código requerido está en manos de nuestra estructura local, es momento de probarlo. Elige tu dispositivo Android y ejecuta la app. En la pantalla principal, presiona Agregar dispositivo y completa los pasos para enviárselo a tu dispositivo.
Cuando se completa la puesta en marcha, el dispositivo ahora participa en dos tejidos: el tejido local de Android y el tejido de desarrollo local. Cada tejido tiene su propio conjunto de credenciales y un ID de tejido único de 64 bits.
6. Controla dispositivos
La asignación a una estructura de desarrollo te permite usar las bibliotecas del repositorio de Matter (connectedhomeip
) para controlar dispositivos desde la app de muestra.
Creamos algunas clases de ayuda para facilitar el acceso a clústeres de dispositivos y el envío de comandos. Para obtener más información, abre ClustersHelper
en java/clusters
. Este asistente de singleton importa las siguientes bibliotecas para acceder a la información del dispositivo:
import chip.devicecontroller.ChipClusters import chip.devicecontroller.ChipStructs
Podemos usar esta clase para obtener el clúster de activación/desactivación de un dispositivo y, luego, llamar a .toggle
:
suspend fun toggleDeviceStateOnOffCluster(deviceId: Long, endpoint: Int) { Timber.d("toggleDeviceStateOnOffCluster())") val connectedDevicePtr = try { chipClient.getConnectedDevicePointer(deviceId) } catch (e: IllegalStateException) { Timber.e("Can't get connectedDevicePointer.") return } return suspendCoroutine { continuation -> getOnOffClusterForDevice(connectedDevicePtr, endpoint) .toggle( object : ChipClusters.DefaultClusterCallback { override fun onSuccess() { continuation.resume(Unit) } override fun onError(ex: Exception) { Timber.e("readOnOffAttribute command failure: $ex") continuation.resumeWithException(ex) } }) } }
Activar o desactivar un dispositivo
Después de encargar un dispositivo, la carga útil que se muestra en CommissioningResult se agrega a DataStore. Esto le da a nuestra aplicación acceso a la información del dispositivo que podemos usar para enviar comandos.
Las apps de Matter son controladas por eventos. Cuando se inicializa la pila Matter, los servicios de clúster detectan mensajes entrantes. Una vez que se realiza la asignación de un dispositivo, los clientes de Matter envían comandos a través del canal operativo seguro que se estableció durante la puesta en marcha del dispositivo.
En el dispositivo, los paquetes se validan, se desencriptan y, luego, se despachan con una devolución de llamada. Las funciones de devolución de llamada incluyen EndpointId, ClusterId y AttributeId, al que se puede acceder desde attributePath
. Por ejemplo, este código se puede implementar en un dispositivo Matter:
void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type, uint16_t size, uint8_t * value) { // handle callback ClusterId clusterId = attributePath.mClusterId; AttributeId attributeId = attributePath.mAttributeId; }
En los próximos pasos, usarás el SDK de Matter y ClustersHelper
para activar o desactivar un dispositivo.
- Ve a
DeviceViewModel
enjava/screens/device
. - Ubica la función
updateDeviceStateOn
. - Reemplaza el comentario
// CODELAB: toggle
por el código para llamar aclustersHelper
y, luego, actualiza el repositorio del dispositivo:Timber.d("Handling real device") try { clustersHelper.setOnOffDeviceStateOnOffCluster(deviceUiModel.device.deviceId, isOn, 1) devicesStateRepository.updateDeviceState(deviceUiModel.device.deviceId, true, isOn) } catch (e: Throwable) { Timber.e("Failed setting on/off state") }
Esta función se llama desde DeviceFragment
:
// Change the on/off state of the device binding.onoffSwitch.setOnClickListener { val isOn = binding.onoffSwitch.isChecked viewModel.updateDeviceStateOn(selectedDeviceViewModel.selectedDeviceLiveData.value!!, isOn) }
Ejecuta la app
Ejecuta la app para volver a cargar tus actualizaciones. En la pantalla principal, activa y desactiva el dispositivo.
7. Comparte dispositivos con otros ecosistemas
En la especificación de Matter, compartir un dispositivo se conoce como flujo de administrador múltiple.
En los pasos anteriores, aprendimos que el SDK de Home para dispositivos móviles permite asignar dispositivos a la estructura de Android local y también a una estructura de desarrollo para la aplicación de muestra. Este es un ejemplo de flujo de varios administradores, en el que los dispositivos se pueden asignar a más de una estructura.
Ahora, tal vez quiera compartir dispositivos con aún más tejidos, especialmente si se trata de una familia en la que las personas tienen sus propias preferencias en cuanto a aplicaciones y plataformas.
El SDK de Home para dispositivos móviles proporciona esta funcionalidad en la API de ShareDeviceRequest, lo que te permite hacer lo siguiente:
- Abre un período de asignación temporal para los dispositivos.
- Cambia el estado de tus dispositivos para que se puedan asignar a otra estructura.
- Controla tus dispositivos desde otras apps y ecosistemas.
En los próximos pasos, usarás el SDK de Home para dispositivos móviles a fin de compartir dispositivos.
Paso 1: Crea un selector de actividad GPS
De manera similar al iniciador de actividades de comisión que creamos cuando se encargó la construcción de una estructura de desarrollo, creamos un Launcher de actividad del dispositivo compartido para manejar el IntentSender
desde la API de CommissioningClient.
- Abre
DeviceFragment
en la carpetajava/screens/device/
. - Reemplaza el comentario
// CODELAB: shareDeviceLauncher definition
por el siguiente código para registrar y controlar el resultado de la actividad de.shareDevice()
:shareDeviceLauncher = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result -> // Share Device Step 5. // The Share Device activity in GPS (step 4) has completed. val resultCode = result.resultCode if (resultCode == RESULT_OK) { Timber.d("ShareDevice: Success") viewModel.shareDeviceSucceeded(selectedDeviceViewModel.selectedDeviceLiveData.value!!) } else { viewModel.shareDeviceFailed( selectedDeviceViewModel.selectedDeviceLiveData.value!!, resultCode) } }
Paso 2: Revisa los objetos LiveData
La devolución de llamada exitosa de la API de .shareDevice()
proporciona el IntentSender
que se usará para iniciar la actividad del dispositivo compartido en los Servicios de Google Play. En el DeviceViewModel
, creamos dos objetos LiveData para informar sobre el resultado de esta llamada a la API:
_shareDeviceStatus
para realizar un seguimiento deTaskStatus
.// The current status of the share device action. viewModel.shareDeviceStatus.observe(viewLifecycleOwner) { status -> val isButtonEnabled = status !is InProgress updateShareDeviceButton(isButtonEnabled) if (status is TaskStatus.Failed) { showAlertDialog(errorAlertDialog, status.message, status.cause!!.toString()) } }
_shareDeviceIntentSender
para controlar el resultado de la llamada a.sharedevice()
.
viewModel.shareDeviceIntentSender.observe(viewLifecycleOwner) { remitente -> Timber.d("shareDeviceIntentSender.observe se llama con [${intentSenderToString(sender)}]") if (sender != null) { // Compartir dispositivo Paso 4: Iniciar la actividad descrita en el IntentSender que // se mostró // en el Paso 3 (donde la vista de llamada llama a la API al dispositivo GPS) Timber.d("ShareDevice: Inicia la actividad de GPS para compartir el dispositivo") shareDeviceLauncher.launch(IntentSenderRequest.Builder(sender).build()) viewModel.consumeShareDeviceIntentSender() } } ```
En los próximos pasos, usaremos estos objetos de LiveData en nuestra llamada a la API de .shareDevice()
.
Paso 3: Llama a la API
Ahora tienes que iniciar una tarea para compartir el dispositivo.
- Abre
DeviceViewModel.kt
en la carpetajava/screens/device/
. - Ubica la función
shareDevice()
. Reemplaza el comentario// CODELAB: shareDevice
por ShareDeviceRequest. ElDeviceDescriptor
proporciona información específica sobre el dispositivo, como el ID de proveedor, el ID de producto y el deviceType. En este ejemplo, codificamos los valores.Timber.d("ShareDevice: Setting up the IntentSender") val shareDeviceRequest = ShareDeviceRequest.builder() .setDeviceDescriptor(DeviceDescriptor.builder().build()) .setDeviceName("temp device name")
- Configura CommissioningWindow y parameters. En este momento, el período de comisión temporal está abierto en el dispositivo.
.setCommissioningWindow( CommissioningWindow.builder() .setDiscriminator(Discriminator.forLongValue(DISCRIMINATOR)) .setPasscode(SETUP_PIN_CODE) .setWindowOpenMillis(SystemClock.elapsedRealtime()) .setDurationSeconds(OPEN_COMMISSIONING_WINDOW_DURATION_SECONDS.toLong()) .build()) .build()
- Llama a
.getCommissioningClient()
, solo esta vez, usa la API de.shareDevice()
. La devolución de llamada exitosa de la API decommissioningClient.shareDevice()
proporciona el IntentSender que se usará para iniciar la actividad del dispositivo compartido en los Servicios de Google Play.Matter.getCommissioningClient(activity) .shareDevice(shareDeviceRequest)
- Para completar nuestra función
shareDevice
, agregaaddOnSuccessListener
yaddOnFailureListener
, y publica en los objetos LiveData:.addOnSuccessListener { result -> Timber.d("ShareDevice: Success getting the IntentSender: result [${result}]") // Communication with fragment is via livedata _backgroundWorkAlertDialogAction.postValue(BackgroundWorkAlertDialogAction.Hide) _shareDeviceIntentSender.postValue(result) } .addOnFailureListener { error -> Timber.e(error) _backgroundWorkAlertDialogAction.postValue(BackgroundWorkAlertDialogAction.Hide) _shareDeviceStatus.postValue( TaskStatus.Failed("Setting up the IntentSender failed", error)) }
Después de usar el remitente, se debe llamar a consumeShareDeviceIntentSender
para evitar recibirlo de nuevo después de un cambio de configuración.
/** * Consumes the value in [_shareDeviceIntentSender] and sets it back to null. Needs to be called * to avoid re-processing an IntentSender after a configuration change where the LiveData is * re-posted. */ fun consumeShareDeviceIntentSender() { _shareDeviceIntentSender.postValue(null) }
Ejecuta la app
Para compartir tu dispositivo Matter con otros ecosistemas, deberás tener instalada otra plataforma en tu dispositivo Android. Creamos otra instancia de la app de muestra que puedes usar como responsable de destino.
Una vez que hayas instalado el encargado objetivo en tu dispositivo Android, verifica que puedes compartir tu dispositivo Matter. La aplicación de comisión encargada de destino tiene la etiqueta GHSAFM-TC.
Los dispositivos ahora pueden participar de tres formas:
- La tela de Android local.
- Tu tejido de desarrollo (esta aplicación).
- La tercera tela con la que acabas de compartir el dispositivo.
8. Próximos pasos
¡Felicitaciones!
¡Felicitaciones! Completaste correctamente este Codelab y aprendiste a encargar y compartir dispositivos con el SDK de Home para dispositivos móviles.
Si tienes problemas con la app de ejemplo, intenta completar los pasos para verificar tu entorno:
Si tienes preguntas sobre el uso de la app de muestra o descubres un error de código, puedes enviar problemas a la Herramienta de seguimiento de errores en el repositorio de GitHub:
Para obtener orientación oficial de Google sobre preguntas técnicas, usa el Foro para desarrolladores de casas inteligentes:
Para obtener asistencia técnica de la comunidad, usa la etiqueta google-smart-home
en Stack Overflow: