Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Importante
La API de notificaciones de Microsoft Graph está en desuso y dejará de devolver datos a finales de enero de 2022. Para obtener una experiencia de notificación alternativa, consulte Microsoft Azure Notification Hubs. Para obtener más información, consulte la entrada de blog Retirada de la API de notificaciones de Microsoft Graph (beta).
Después de registrar la aplicación en el Centro de administración Microsoft Entra e incorporar las experiencias entre dispositivos en el Centro de desarrollo de partners, el siguiente paso es integrar la aplicación cliente con el SDK del lado cliente para aplicaciones Android.
Con el SDK de cliente, la aplicación puede realizar los pasos de registro necesarios para empezar a recibir notificaciones publicadas desde el servidor de aplicación dirigidas al usuario que ha iniciado sesión. Luego, el SDK administra las notificaciones en el lado cliente y se encarga de recibir nuevas notificaciones entrantes, administrar el estado de notificaciones para conseguir escenarios como el descarte universal y recuperar el historial completo de notificaciones.
Nuevo flujo de notificaciones entrantes
Para recibir nuevas notificaciones entrantes, se muestra el flujo de datos en el siguiente diagrama.
El proceso incluye algunos componentes:
- Servidor de aplicaciones: el back-end de la aplicación
- Cliente de la aplicación: el front-end de la aplicación (una aplicación UWP, una aplicación de Android o una aplicación de iOS)
- Notificaciones de Microsoft Graph: el componente del servicio que permite publicar, almacenar y sincronizar las notificaciones de usuario entre diferentes instancias de clientes de la aplicación en varios dispositivos y plataformas
- FCM (Firebase Cloud Messaging): el servicio de notificaciones de inserción que proporciona Android como parte de Google Play Services. Las notificaciones de Microsoft Graph usan este servicio para señalar a los clientes de aplicación de Android los cambios de datos de notificación de usuario.
El diagrama muestra los pasos siguientes:
- Lógica de la aplicación. Este paso captura lo que activa la notificación que se publicará para el usuario. Esta es la lógica específica de la aplicación y puede ser una actualización de eventos o datos sobre algo más en Microsoft Graph, como un evento de calendario o una asignación de tarea, o bien el servicio de aplicaciones que quiere notificar al usuario.
- El servidor de aplicaciones publica una notificación para el usuario de destino a través de la API de notificaciones de Microsoft Graph. Para obtener más información, vea integración del lado servidor.
- Al recibir la solicitud web que contiene la nueva notificación, las notificaciones de Microsoft Graph conservan el contenido de la notificación de forma segura en la nube para esta aplicación y este usuario.
- Para cada instancia del cliente de la aplicación que se subscriba para recibir notificaciones para este usuario, las notificaciones de Microsoft Graph envían una señal para notificar al cliente de la aplicación, mediante el servicio de inserción nativo que proporciona el sistema operativo. En este caso, la aplicación es una aplicación para Android y usa el mensaje de datos FCM para enviar la señal.
- Después de que la notificación de inserción entrante señale la aplicación, se pide al SDK que obtenga los cambios en el almacén de notificaciones de usuario.
- El SDK establece una conexión segura y conforme con el almacén de notificaciones de usuario en Microsoft Graph.
- El SDK obtiene los cambios de datos, en este caso, el contenido de la nueva notificación.
- El SDK desencadena la devolución de la llamada de evento para notificar a la aplicación cuando se recuperen correctamente los cambios.
- Lógica de la aplicación. Este paso captura lo que la aplicación decide realizar dentro de la devolución de llamada de evento. Normalmente, esto resulta en cambios de datos de la aplicación local y actualizaciones de la interfaz de usuario local. En este caso, la aplicación suele crear un elemento emergente de notificación del sistema para notificar al usuario sobre el contenido de la notificación.
Flujo de actualización de notificaciones
Una de las principales ventajas del uso de las notificaciones de Microsoft Graph es que conservan las notificaciones en la nube de forma segura y las convierte en un tipo de recurso con estado. Por ello, puede ayudar a la aplicación a administrar y sincronizar el estado correcto de las notificaciones en varios dispositivos para el mismo usuario que ha iniciado sesión en varios dispositivos. Cuando se marca una notificación como descartada o leída en un dispositivo, los demás dispositivos pueden ser notificados en tiempo real. "Controlada una vez, descartada en todas partes" puede ser una verdadera promesa como parte de la experiencia de notificación de los usuarios.
El siguiente diagrama muestra el flujo de datos para cambiar el estado de una notificación o eliminar la notificación en un dispositivo, la recepción y manipulación del cambio de estado o la eliminación en otro dispositivo.
Observe que la segunda parte del flujo es similar al flujo para controlar las nuevas notificaciones entrantes. Esto es por diseño: el patrón de programación del SDK está diseñado para que el cliente de la aplicación pueda controlar todos los tipos de cambios de datos de notificación de usuario (nuevas notificaciones entrantes, cambios de estado de notificación, notificaciones eliminadas) de forma similar.
El diagrama muestra los pasos siguientes:
- Lógica de la aplicación. Algo desencadena el cambio o la eliminación de la notificación. En general, cualquier evento puede desencadenar el cambio de una notificación.
- La aplicación llama al SDK del cliente para actualizar o eliminar una notificación. Actualmente, exponemos dos propiedades sobre los cambios de estado, userActionState y readState, pero la aplicación puede definir estos estados y cuándo deben actualizarse. Por ejemplo, cuando un usuario descarta la notificación emergente, puede actualizar userActionState como Descartado. Cuando un usuario hace clic en la notificación emergente e inicia la aplicación para consumir contenido de aplicación correspondiente, puede actualizar userActionState como Activado y readState como Leído.
- Después de llamar a la API correspondiente para actualizar o eliminar una notificación, el SDK realizará una llamada al almacén de notificaciones del usuario en la nube para distribuir este cambio a las demás instancias de cliente de la aplicación con el mismo usuario que ha iniciado sesión.
- Al recibir la solicitud de actualización o eliminación de un cliente, las notificaciones de Microsoft Graph actualizan el almacén de notificaciones e identifican las demás instancias del cliente de la aplicación que se suscribió a este cambio.
- Para cada suscripción del cliente de la aplicación, las notificaciones de Microsoft Graph envían una señal para notificar al cliente de la aplicación, mediante el servicio de inserción nativo que proporciona el sistema operativo. En este caso, se trata de una aplicación para Android y usa el mensaje de datos FCM para enviar la señal.
- Después de que la notificación de inserción entrante señale la aplicación, se pide al SDK que obtenga los cambios en el almacén de notificaciones de usuario.
- El SDK establece una conexión segura y conforme con el almacén de notificaciones de usuario en Microsoft Graph.
- El SDK obtiene los cambios de datos, en este caso, las actualizaciones de estado de notificación o las eliminaciones de las notificaciones.
- El SDK desencadena la devolución de la llamada de evento para notificar a la aplicación cuando se recuperen correctamente los cambios.
- Lógica de la aplicación. Este paso captura lo que la aplicación decide realizar dentro de la devolución de llamada de evento. Normalmente, esto resulta en cambios de datos de la aplicación local y actualizaciones de la interfaz de usuario local. En este caso, como hay actualizaciones de notificación, la aplicación debe actualizar la interfaz de usuario local para reflejar el cambio de estado. Por ejemplo, si una notificación se marca como activada, puede quitar el mensaje de notificación correspondiente en la bandeja de notificaciones de Android para lograr el "controlada una vez, descartada en todas partes".
Para obtener más información sobre las notificaciones de Microsoft Graph, vea Introducción a las notificaciones de Microsoft Graph. Para obtener más información sobre los pasos necesarios para integrar las notificaciones de Microsoft Graph de un extremo a otro, vea la Introducción a la integración de las notificaciones de Microsoft Graph.
Requisitos y entorno de desarrollo
Para usar las notificaciones de Microsoft Graph, necesitará un IDE de desarrollo de aplicaciones para Android y un dispositivo Android con una de las arquitecturas compatibles (armeabi-v7a, arm64-v8a, x86 o x86_64) o un emulador. El sistema debe ejecutar Android 4.4.2 o posterior.
Agregar el SDK al proyecto
Inserte las siguientes referencias del repositorio en el archivo build.gradle en la raíz del proyecto.
allprojects {
repositories {
jcenter()
maven { url 'https://maven.google.com' }
maven { url 'https://projectrome.bintray.com/maven/' }
}
}
Luego, inserte la siguiente dependencia en el archivo build.gradle que se encuentra en la carpeta del proyecto.
dependencies {
...
implementation 'com.microsoft.connecteddevices:connecteddevices-sdk:+'
}
Si quiere usar ProGuard en la aplicación, agregue las reglas ProGuard para estas nuevas API. Cree un archivo denominado proguard-rules.txt en la carpeta App del proyecto y pegue el contenido de ProGuard_Rules_for_Android_Rome_SDK.txt
.
En el archivo AndroidManifest.xml del proyecto, agregue los permisos siguientes en el elemento manifest
(si aún no están presentes). Esto proporciona a la aplicación los permisos para conectarse a Internet y habilitar la detección de Bluetooth en el dispositivo.
Tenga en cuenta que los permisos relacionados con el Bluetooth solo son necesarios para usar la detección de Bluetooth; no son necesarios para el resto de las características de la Plataforma de dispositivos conectados. Además, ACCESS_COARSE_LOCATION
solo es necesario en los SDK 21 de Android y posterior. En los SDK 23 de Android y posterior, también debe solicitar al usuario que conceda acceso a la ubicación en tiempo de ejecución.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Luego, vaya a las clases de actividades donde quiere ubicar la funcionalidad de los dispositivos conectados. Importe los siguientes espacios de nombres.
import com.microsoft.connecteddevices;
import com.microsoft.connecteddevices.userdata;
import com.microsoft.connecteddevices.userdata.usernotifications;
Iniciar las Plataformas de dispositivos conectados
El SDK del lado cliente se basa en una infraestructura llamada Plataforma de dispositivos conectados. Antes de poder utilizar cualquier característica, se debe inicializar la plataforma en la aplicación. Los pasos de inicialización deberían aparecer en el método de la clase principal OnCreate, ya que son necesarios antes de que puedan tener lugar los escenarios de notificación.
Debe crear e iniciar la plataforma con una instancia de la clase ConnectedDevicesPlatform. Antes de hacerlo, asegúrese de conectar los controladores de eventos, porque después de iniciar la plataforma, puede que los eventos comiencen a activarse.
ConnectedDevicesPlatform platform = new ConnectedDevicesPlatform(context);
platform.getAccountManager().accessTokenRequested().subscribe((accountManager, args) -> onAccessTokenRequested(accountManager, args));
platform.getAccountManager().accessTokenInvalidated().subscribe((accountManager, args) -> onAccessTokenInvalidated(accountManager, args));
platform.getNotificationRegistrationManager().notificationRegistrationStateChanged().subscribe((notificationRegistrationManager, args) -> onNotificationRegistrationStateChanged(notificationRegistrationManager, args));
platform.start();
Controlar el token de acceso de la cuenta
Todas las llamadas web que realiza el SDK, incluidas las llamadas para recuperar el contenido de una nueva notificación entrante, actualizar los estados de notificación y mucho más, leen de o escriben en los datos del usuario y, por ello, siempre requieren un token de acceso válido. El SDK requiere que controle los eventos siguientes, invocados cuando se solicita o se invalida un token de acceso, para asegurarse de que una vez iniciada la plataforma, el token de acceso para el usuario se controla correctamente.
accessTokenRequested
Para una implementación completa, vea la Aplicación de ejemplo para Android.
private void onAccessTokenRequested(ConnectedDevicesAccountManager sender, ConnectedDevicesAccessTokenRequestedEventArgs args) {
ConnectedDevicesAccessTokenRequest request = args.getRequest();
List<String> scopes = request.getScopes();
// We always need to complete the request, even if a matching account is not found
if (account == null) {
request.completeWithErrorMessage("The app could not find a matching ConnectedDevicesAccount to get a token");
return;
}
// Complete the request with a token
account.getAccessTokenAsync(scopes)
.thenAcceptAsync((String token) -> {
request.completeWithAccessToken(token);
}).exceptionally(throwable -> {
request.completeWithErrorMessage("The Account could not return a token with those scopes");
return null;
});
}
accessTokenInvalidated
Para una implementación completa, vea la Aplicación de ejemplo para Android.
private void onAccessTokenInvalidated(ConnectedDevicesAccountManager sender, ConnectedDevicesAccessTokenInvalidatedEventArgs args, List<Account> accounts) {
Log.i(TAG, "Token invalidated for account: " + args.getAccount().getId());
}
Controlar la expiración del registro push
Las notificaciones de Microsoft Graph usan FCM, la plataforma de inserción nativa de Android, para señalar a la aplicación cliente los cambios de datos de notificaciones de usuario. Esto ocurre cuando nuevas notificaciones entrantes se publican desde el servidor de aplicaciones o cuando se actualiza el estado de las notificaciones en otro dispositivo con el mismo usuario que ha iniciado sesión en un escenario con varios dispositivos.
Por lo tanto, es necesario un token válido FCM que permita que los mensajes de notificación de datos lleguen correctamente. La siguiente devolución de llamada de evento controla la expiración del token de inserción FCM.
notificationRegistrationStateChanged
Para una implementación completa, vea la Aplicación de ejemplo para Android.
Hacer que el usuario inicie sesión
Las notificaciones de Microsoft Graph, como muchos otros tipos de recursos de Microsoft Graph, están centralizadas en los usuarios. Para que la aplicación se suscriba y empiece a recibir notificaciones para el usuario que ha iniciado sesión, primero debe obtener un token de OAuth válido que se usará en el proceso de registro. Puede usar el método preferido para crear y administrar los tokens de OAuth. La aplicación de ejemplo usó ADAL.
Si usa una cuenta de Microsoft, deberá incluir los permisos siguientes en la solicitud de inicio de sesión: wl.offline_access"
, ccs.ReadWrite
, wns.connect
, asimovrome.telemetry
y https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp
.
Si usa una cuenta de Microsoft Entra, deberá solicitar la siguiente audiencia: https://cdpcs.access.microsoft.com
.
Agregar la cuenta del usuario a la plataforma
Debe registrar la cuenta del usuario que ha iniciado sesión con el SDK, lo que implica agregar la cuenta y registrar un canal de inserción para recibir las notificaciones de inserción iniciales por FCM.
public AsyncOperation<Boolean> prepareAccountAsync(final Context context) {
// Accounts can be in 3 different scenarios:
// 1: cached account in good standing (initialized in the SDK and our token cache).
// 2: account missing from the SDK but present in our cache: Add and initialize account.
// 3: account missing from our cache but present in the SDK. Log the account out async
// Subcomponents (e.g. UserDataFeed) can only be initialized when an account is in both the app cache
// and the SDK cache.
// For scenario 1, initialize our subcomponents.
// For scenario 2, subcomponents will be initialized after InitializeAccountAsync registers the account with the SDK.
// For scenario 3, InitializeAccountAsync will unregister the account and subcomponents will never be initialized.
switch (mState) {
// Scenario 1
case IN_APP_CACHE_AND_SDK_CACHE:
mUserNotificationsManager = new UserNotificationsManager(context, mAccount, mPlatform);
return registerAccountWithSdkAsync();
// Scenario 2
case IN_APP_CACHE_ONLY: {
// Add the this account to the ConnectedDevicesPlatform.AccountManager
return mPlatform.getAccountManager().addAccountAsync(mAccount).thenComposeAsync((ConnectedDevicesAddAccountResult result) -> {
// We failed to add the account, so exit with a failure to prepare bool
if (result.getStatus() != ConnectedDevicesAccountAddedStatus.SUCCESS) {
result.getStatus());
return AsyncOperation.completedFuture(false);
}
// Set the registration state of this account as in both app and sdk cache
mState = AccountRegistrationState.IN_APP_CACHE_AND_SDK_CACHE;
mUserNotificationsManager = new UserNotificationsManager(context, mAccount, mPlatform);
return registerAccountWithSdkAsync();
});
}
// Scenario 3
case IN_SDK_CACHE_ONLY:
// Remove the account from the SDK since the app has no knowledge of it
mPlatform.getAccountManager().removeAccountAsync(mAccount);
// This account could not be prepared
return AsyncOperation.completedFuture(false);
default:
// This account could not be prepared
Log.e(TAG, "Failed to prepare account " + mAccount.getId() + " due to unknown state!");
return AsyncOperation.completedFuture(false);
}
}
public AsyncOperation<Boolean> registerAccountWithSdkAsync() {
if (mState != AccountRegistrationState.IN_APP_CACHE_AND_SDK_CACHE) {
AsyncOperation<Boolean> toReturn = new AsyncOperation<>();
toReturn.completeExceptionally(new IllegalStateException("Cannot register this account due to bad state: " + mAccount.getId()));
return toReturn;
}
// Grab the shared GCM/FCM notification token from this app's BroadcastReceiver
return RomeNotificationReceiver.getNotificationRegistrationAsync().thenComposeAsync((ConnectedDevicesNotificationRegistration notificationRegistration) -> {
// Perform the registration using the NotificationRegistration
return mPlatform.getNotificationRegistrationManager().registerAsync(mAccount, notificationRegistration)
.thenComposeAsync((result) -> {
if (result.getStatus() == ConnectedDevicesNotificationRegistrationStatus.SUCCESS) {
Log.i(TAG, "Successfully registered account " + mAccount.getId() + " for cloud notifications");
} else {
// It would be a good idea for apps to take a look at the different statuses here and perhaps attempt some sort of remediation.
// For example, token request failed could mean that the user needs to sign in again. An app could prompt the user for this action
// and retry the operation afterwards.
Log.e(TAG, "Failed to register account " + mAccount.getId() + " for cloud notifications!");
return AsyncOperation.completedFuture(false);
}
return mUserNotificationsManager.registerForAccountAsync();
});
});
}
Suscribirse para recibir notificaciones de usuario
Deberá crear una instancia de un objeto UserDataFeed de la aplicación para el usuario que ha iniciado sesión. La aplicación se identifica con el Id. de aplicación multiplataforma que proporcionó durante la Incorporación a experiencias en varios dispositivos.
public UserNotificationsManager(@NonNull Context context, @NonNull ConnectedDevicesAccount account, @NonNull ConnectedDevicesPlatform platform)
{
Context context = new Context;
UserDataFeed feed = UserDataFeed.getForAccount(account, platform, Secrets.APP_HOST_NAME);
UserNotificationChannel channel = new UserNotificationChannel(feed);
UserNotificationReader reader = channel.createReader();
reader.dataChanged().subscribe((reader, aVoid) -> readFromCache(reader));
}
}
Recibir y administrar las notificaciones de usuario
El diagrama de flujo representado anteriormente en este tema muestra que los patrones de programación para controlar nuevas notificaciones entrantes desde un servidor de aplicaciones y una actualización o eliminación de notificación iniciadas desde otra instancia de cliente de aplicación son similares. Estos son los pasos para controlar los cambios de los datos.
Controlar la señal de notificación de inserción entrante
Todos los tipos de cambios de datos de notificación de usuario crean una señal que se entrega a los clientes de aplicación, como una notificación de inserción. Para las aplicaciones de Android, se envía la señal como un mensaje de datos de inserción de FCM. Al recibir la señal del mensaje de datos, la aplicación debe llamar a TryParse para desencadenar el SDK y obtener los cambios de datos reales desde el servicio de notificaciones de Microsoft Graph.
public void onMessageReceived(RemoteMessage message) {
Map data = message.getData();
ConnectedDevicesNotification notification = ConnectedDevicesNotification.tryParse(data);
if (notification != null) {
try {
ConnectedDevicesPlatform platform = ConnectedDevicesManager.getConnectedDevicesManager(getApplicationContext()).getPlatform();
// NOTE: it may be useful to attach completion to this async in order to know when the notification is done being processed.
// This would be a good time to stop a background service or otherwise cleanup.
platform.processNotificationAsync(notification);
} catch (Exception e) {
Log.e(TAG, "Failed to process FCM notification" + e.getMessage());
}
}
}
Controlar los cambios de datos de notificación de usuario
Después de que el SDK haya obtenido los cambios de datos, se invoca una devolución de llamada de evento y se espera que el cliente de aplicación controle la creación, actualización o eliminación de la notificación.
private void readFromCache(final UserNotificationReader reader)
{
reader.readBatchAsync(Long.MAX_VALUE).thenAccept(notifications -> {
synchronized (this) {
for (final UserNotification notification : notifications) {
if (notification.getStatus() == UserNotificationStatus.ACTIVE) {
removeIf(mNewNotifications, item -> notification.getId().equals(item.getId()));
if (notification.getUserActionState() == UserNotificationUserActionState.NO_INTERACTION) {
mNewNotifications.add(notification);
if (notification.getReadState() != UserNotificationReadState.READ) {
clearNotification(mContext.getApplicationContext(), notification.getId());
addNotification(mContext.getApplicationContext(), notification.getContent(), notification.getId());
}
} else {
clearNotification(mContext.getApplicationContext(), notification.getId());
}
removeIf(mHistoricalNotifications, item -> notification.getId().equals(item.getId()));
mHistoricalNotifications.add(0, notification);
} else {
removeIf(mNewNotifications, item -> notification.getId().equals(item.getId()));
removeIf(mHistoricalNotifications, item -> notification.getId().equals(item.getId()));
clearNotification(mContext.getApplicationContext(), notification.getId());
}
}
}
});
}
Actualizar el estado de una notificación
Si se inicia un cambio de estado de notificación de esta instancia del cliente de aplicación (por ejemplo, si un usuario ha activado la notificación del sistema emergente en este dispositivo), la aplicación debe llamar al SDK para actualizar el estado de la notificación para que este cambio de estado se sincronice en todos los dispositivos que usa el mismo usuario.
notification.setUserActionState(UserNotificationUserActionState.ACTIVATED);
notification.saveAsync().whenCompleteAsync((userNotificationUpdateResult, throwable) -> {
if (throwable == null && userNotificationUpdateResult != null && userNotificationUpdateResult.getSucceeded()) {
Log.d(TAG, "Successfully activated the notification");
}
});
Eliminar una notificación
Si la eliminación de una notificación se inicia desde esta instancia de cliente de aplicación (por ejemplo, si la tarea correspondiente a esta notificación se marca como completada y se elimina de la base de datos de la aplicación), la aplicación debe llamar al SDK para eliminar la notificación y sincronizar esta operación de eliminación en todos los dispositivos que ha usado el mismo usuario.
Una notificación se elimina del almacén de notificaciones del usuario solo si ha expirado o se ha eliminado de forma explícita. No se elimina la notificación de usuario al actualizar UserActionState como Descartado, porque la definición semántica de UserActionState la define la misma aplicación.
channel.deleteUserNotificationAsync(notification.getId()).whenCompleteAsync((userNotificationUpdateResult, throwable) -> {
if (throwable == null && userNotificationUpdateResult != null && userNotificationUpdateResult.getSucceeded()) {
Log.d(TAG, "Successfully deleted the notification");
}
});
Contenido relacionado
- Referencia de la API para todo el conjunto de API relacionadas con las características de notificación de SDK.
- Ejemplo del lado cliente para aplicaciones de Android.
- Ejemplo de servidor de aplicaciones para publicar notificaciones.