Freigeben über


Schrittanleitung: Integration in Graph-Benachrichtigungen (Android)

Mithilfe von Graph-Benachrichtigungen kann Ihre App geräteübergreifend Benachrichtigungen für Benutzer senden und verwalten.

Mit dem clientseitigen Project Rome-SDK unter Android kann Ihre Android-App für den Empfang der vom App-Server veröffentlichten Benachrichtigungen für angemeldete Benutzer registriert werden. Mithilfe des SDK kann der App-Client neue eingehende Benachrichtigungsnutzlasten empfangen, den Status der vorhandenen Benachrichtigungen verwalten und den Benachrichtigungsverlauf abrufen. Weitere Informationen über Benachrichtigungen und die Übermittlung benutzerzentrierter Benachrichtigungen finden Sie unter Microsoft Graph-Benachrichtigungen

Alle Features im Project Rome-SDK, einschließlich Graph-Benachrichtigungen, bauen auf einer Plattform auf, die als Plattform für verbundene Geräte bezeichnet wird. Diese Anleitung führt Sie durch die erforderlichen Schritte für die Verwendung der Plattform für verbundene Geräte, und es wird erläutert, wie mit den APIs im SDK spezielle Features von Graph-Benachrichtigungen implementiert werden.

Auf der Seite API-Referenz finden Sie Links zur Referenzdokumentation für Benachrichtigungsszenarien.

In den folgenden Schritten wird auf Code aus der Android-Beispiel-App für Project Rome verwiesen.

Für alle Funktionen der Plattform für verbundene Geräte benötigen Sie eine IDE für die Android-App-Entwicklung und ein Android-Gerät mit einer der unterstützten Architekturen (armeabi-v7a, arm64-v8a, x86 oder x86_64) oder einen Emulator. Auf dem System muss Android 4.4.2 oder höher ausgeführt werden.

Vorläufige Einrichtung für die Plattform für verbundene Geräte und Benachrichtigungen

Vor dem Implementieren von Remoteverbindungen müssen Sie einige Schritte ausführen, damit Ihre Android-App eine Verbindung mit externen Geräten herstellen sowie Benachrichtigungen senden und empfangen kann.

Registrieren der App

Fast alle Features des Project Rome-SDK, mit Ausnahme der Umgebungsfreigabe-APIs, erfordern MSA-Authentifizierung (Microsoft Account) oder AAD-Authentifizierung (Azure Active Directory). Wenn Sie noch kein MSA haben, jedoch ein MSA verwenden möchten, registrieren Sie sich auf account.microsoft.com.

Hinweis

AAD-Konten (Azure Active Directory) werden für Device Relay-APIs nicht unterstützt.

Sie müssen Ihre App mit der gewählten Authentifizierungsmethode gemäß den Anweisungen im App-Registrierungsportal bei Microsoft registrieren. Wenn Sie über kein Microsoft Developer-Konto verfügen, müssen Sie eines erstellen.

Wenn Sie eine App mit einem MSA registrieren, erhalten Sie eine Client-ID-Zeichenfolge. Speichern Sie diese zur späteren Verwendung. Dadurch erhält Ihre App Zugriff auf Ressourcen der Microsoft-Plattform für verbundene Geräte. Wenn Sie AAD verwenden, finden Sie unter Azure Active Directory-Authentifizierungsbibliotheken Anweisungen zum Abrufen der Client-ID-Zeichenfolge.

Hinzufügen des SDK

Fügen Sie die folgenden Repositoryverweise in die build.gradle-Datei im Stammverzeichnis des Projekts ein.

allprojects {
    repositories {
        jcenter()
    }
}

Fügen Sie anschließend die folgende Abhängigkeit in die build.gradle-Datei ein, die sich im Projektordner befindet.

dependencies { 
    ...
    implementation 'com.microsoft.connecteddevices:connecteddevices-sdk:+'
}

Fügen Sie in der Datei AndroidManifest.xml des Projekts im <manifest>-Element die folgenden Berechtigungen hinzu (sofern sie nicht bereits vorhanden sind). Dadurch erhält die App die Berechtigung, eine Verbindung mit dem Internet herzustellen und die Bluetooth-Erkennung auf dem Gerät zu aktivieren.

Beachten Sie, dass die Berechtigungen für Bluetooth nur für die Bluetooth-Erkennung und nicht für die anderen Features der Plattform für verbundene Geräte erforderlich sind. Zudem ist ACCESS_COARSE_LOCATION nur für Android-SDKs der API-Ebene 21 und höher erforderlich. Für Android-SDKs der API-Ebene 23 und höher muss der Entwickler auch implementieren, dass der Benutzer zur Laufzeit zum Gewähren der Ortung aufgefordert wird.

<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" />

Als Nächstes wechseln Sie zu der/den Aktivitätsklasse(n), in der/denen die Funktionalität der Plattform für verbundene Geräte enthalten sein soll. Importieren Sie die folgenden Pakete.

import com.microsoft.connecteddevices;
import com.microsoft.connecteddevices.remotesystems;
import com.microsoft.connecteddevices.remotesystems.commanding;

Einrichten von Authentifizierung und Kontoverwaltung

Die Plattform für verbundene Geräte erfordert, dass bei der Registrierung ein gültiges OAuth-Token verwendet wird. Sie können Ihre bevorzugte Methode zum Generieren und Verwalten der OAuth-Token verwenden. Um jedoch Entwicklern die ersten Schritte mit der Plattform zu erleichtern, wird in der Beispiel-App für Android ein Authentifizierungsanbieter bereitgestellt, der Aktualisierungstoken generiert und verwaltet.

Wenn Sie die ConnectedDevicesAccountManager-Schnittstelle selbst implementieren möchten, beachten Sie die folgenden Informationen:

Wenn Sie ein MSA verwenden, müssen Sie die folgenden Bereiche in die Anmeldeanforderung einschließen: "wl.offline_access", "ccs.ReadWrite", "dds.read", "dds.register", "wns.connect", "asimovrome.telemetry" und "https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp".

Wenn Sie ein AAD-Konto verwenden, müssen Sie die folgenden Zielgruppen anfordern: "https://cdpcs.access.microsoft.com", "https://cs.dds.microsoft.com", "https://wns.windows.com/" und "https://activity.microsoft.com".

Hinweis

AAD-Konten (Azure Active Directory) werden für Device Relay-APIs nicht unterstützt.

Bei Verwendung von AAD müssen Sie unabhängig davon, ob Sie die bereitgestellte ConnectedDevicesAccountManager-Implementierung verwenden, in der Registrierung der App im Azure-Portal (portal.azure.com > „Azure Active Directory“ > „App-Registrierungen“) die folgenden Berechtigungen angeben:

  • Microsoft-Dienst für Aktivitätsfeeds
    • Bereitstellen und Ändern von Benutzerbenachrichtigungen für diese App
    • Lesen und Schreiben von App-Aktivitäten in den/aus dem Aktivitätsfeed des Benutzers
  • Windows-Benachrichtigungsdienst
    • Verbinden des Geräts mit dem Windows-Benachrichtigungsdienst
  • Microsoft-Geräteverzeichnisdienst
    • Siehe die Liste der Geräte
    • Muss der Liste der Geräte und Apps hinzugefügt
  • Microsoft-Befehlsdienst
    • Kommunizieren mit Benutzergeräten
    • Lesen von Benutzergeräten

Registrieren der App für Pushbenachrichtigungen

Registrieren Sie Ihre Anwendung bei Google für die Unterstützung von Firebase Cloud Messaging. Notieren Sie sich die Absender-ID und den Serverschlüssel, die Sie erhalten. Sie werden diese später benötigen.

Nach der Registrierung müssen Sie der Plattform für verbundene Geräte in der App die Pushbenachrichtigungsfunktionalität zuordnen.

mNotificationRegistration = new ConnectedDevicesNotificationRegistration();
mNotificationRegistration.setType(ConnectedDevicesNotificationType.FCM);
mNotificationRegistration.setToken(token);
mNotificationRegistration.setAppId(Secrets.FCM_SENDER_ID);
mNotificationRegistration.setAppDisplayName("SampleApp");

Registrieren der App im Microsoft Windows Dev Center für die geräteübergreifende Nutzung

Wichtig

Dieser Schritt ist nur erforderlich, wenn Sie die Project Rome-Features verwenden möchten, um von Nicht-Windows-Geräten auf Daten zuzugreifen oder Anforderungen zu senden. Wenn die Features nur für Windows-Geräte vorgesehen sind, brauchen Sie diesen Schritt nicht durchzuführen.

Wechseln Sie zum Dev Center-Dashboard, navigieren Sie im linken Navigationsbereich zu „Cross-Device Experiences“ (Geräteübergreifende Nutzung), und wählen Sie die Option zum Konfigurieren einer neuen geräteübergreifenden App aus, wie unten dargestellt. Dev Center-Dashboard – „Cross-Device Experiences“ (Geräteübergreifende Nutzung)

Der Dev Center-Onboardingprozess erfordert die folgenden Schritte:

  • „Select supported platforms“ (Unterstützte Plattformen auswählen): Wählen Sie die Plattformen aus, auf denen Ihre App präsent sein wird und die für die geräteübergreifende Nutzung aktiviert werden sollen. Im Falle der Integration von Graph-Benachrichtigungen können Sie Windows, Android und/oder iOS auswählen, „Cross-Device Experiences“ (Geräteübergreifende Nutzung) – „Supported Platforms“ (Unterstützte Plattformen)

  • „Provide app IDs“ (App-IDs angeben): Stellen Sie App-IDs für jede Plattform bereit, auf der Ihre App präsent ist, Für Android-Apps ist dies der Paketname, den Sie der App beim Erstellen des Projekts zugewiesen haben. Den Paketnamen finden Sie in der Firebase-Konsole unter „Project Overview“ (Projektübersicht) > „General“ (Allgemein). Sie können verschiedene IDs (bis zu zehn) pro Plattform hinzufügen. Dies ist sinnvoll, wenn mehrere Versionen der App vorhanden sind oder wenn Sie über mehrere Apps verfügen, die dieselbe vom App-Server gesendete Benachrichtigung empfangen sollen, die für denselben Benutzer vorgesehen ist. „Cross-Device Experiences“ (Geräteübergreifende Nutzung) – App-IDs

  • Geben Sie die App-IDs von der MSA- und/oder AAD-App-Registrierung an, oder wählen Sie sie aus. Diese der MSA- oder AAD-App-Registrierung entsprechenden Client-IDs wurden in den oben beschriebenen Schritten für die MSA-/AAD-App-Registrierung erlangt. „Cross-Device Experiences“ (Geräteübergreifende Nutzung) – MSA- und AAD-App-Registrierung

  • Graph-Benachrichtigungen und andere Funktionen der Plattform für verbundene Geräte nutzen die jeweiligen nativen Benachrichtigungsplattformen der wichtigsten Plattformen zum Senden von Benachrichtigungen an die App-Client-Endpunkte, d.h. WNS (für UWP von Windows), FCM (für Android) und APNs (für iOS). Geben Sie Ihre Anmeldeinformationen für diese Benachrichtigungsplattformen an, damit Graph-Benachrichtigungen Benachrichtigungen für den App-Server übermitteln kann, wenn Sie Benachrichtigungen für Benutzer veröffentlichen. Für Android erfordert die Verwendung von Microsoft Graph-Benachrichtigungen das Aktivieren des Cloud Messaging-Diensts. Beachten Sie zudem, dass die erforderliche Absender-ID der Firebase Cloud Messaging-Absender-ID und der API-Schlüssel dem Legacy-Serverschlüssel entsprechen muss. Beide befinden sich in der Firebase-Konsole > „Project“ (Projekt) > „Settings“ (Einstellungen) auf der Registerkarte „Cloud Messaging“, wie im Screenshot dargestellt. „Cross-Device Experiences“ (Geräteübergreifende Nutzung) – Pushanmeldeinformationen

  • Der letzte Schritt ist das Überprüfen der Domäne für die geräteübergreifende App. Dabei wird überprüft, ob Ihre App Besitzer der Domäne ist. Dies entspricht einer geräteübergreifenden App-Identität für die App, die Sie registriert haben. „Cross-Device Experiences“ (Geräteübergreifende Nutzung) – Domänenüberprüfung

Initialisieren eines Kanals für Graph-Benachrichtigungen

Mit dem Project Rome-SDK kann Ihre App unterschiedliche Kanäle abonnieren, um verschiedene Typen von Benutzerdaten zu empfangen und zu verwalten – einschließlich Graph-Benachrichtigungen, Benutzeraktivitäten u.v.m. Diese werde alle in UserDataFeed gespeichert und synchronisiert. UserNotification ist die Klasse und der Datentyp, die einer über Graph-Benachrichtigungen gesendeten Benachrichtigung für Benutzer entsprechen. Für die Integration in Graph-Benachrichtigungen und den Empfang einer vom App-Server veröffentlichten UserNotification müssen Sie zunächst den Benutzerdatenfeed initialisieren, indem Sie einen UserNotificationChannel erstellen. Sie sollten dabei wie im obigen Schritt für die Plattforminitialisierung vorgehen: Immer wenn die App in den Vordergrund gelangt (jedoch nicht vor der Plattforminitialisierung) sollte dies überprüft und möglicherweise wiederholt werden.

Mit den folgenden Methoden wird ein UserNotificationChannel initialisiert.

private UserNotificationChannel mNotificationChannel;
private UserDataFeed mUserDataFeed;

// ...

/**
 * Initializes the UserNotificationFeed.
 */
public void initializeUserNotificationFeed() {

    // define what scope of data this app needs
    SyncScope[] scopes = { UserNotificationChannel.getSyncScope() };

    // Get a reference to the UserDataFeed. This method is defined below
    mUserDataFeed = getUserDataFeed(scopes, new EventListener<UserDataFeed, Void>() {
        @Override
        public void onEvent(UserDataFeed userDataFeed, Void aVoid) {
            if (userDataFeed.getSyncStatus() == UserDataSyncStatus.SYNCHRONIZED) {
                // log synchronized.
            } else {
                // log synchronization not completed.
            }
        }
    });

    // this method is defined below
    mNotificationChannel = getUserNotificationChannel();
}

// instantiate the UserDataFeed
private UserDataFeed getUserDataFeed(SyncScope[] scopes, EventListener<UserDataFeed, Void> listener) {
    UserAccount[] accounts = AccountProviderBroker.getSignInHelper().getUserAccounts();
    if (accounts.length <= 0) {
        // notify the user that sign-in is required
        return null;
    }

    // use the initialized Platform instance, along with the cross-device app ID.
    UserDataFeed feed = UserDataFeed.getForAccount(accounts[0], PlatformBroker.getPlatform(), Secrets.APP_HOST_NAME);
    feed.addSyncStatusChangedListener(listener);
    feed.addSyncScopes(scopes);
    // sync data with the server
    feed.startSync();
    return feed;
}

// use the UserDataFeed reference to create a UserActivityChannel
@Nullable
private UserNotificationChannel getUserNotificationChannel() {
    UserNotificationChannel channel = null;
    try {
        // create a UserNotificationChannel for the signed in account
        channel = new UserNotificationChannel(mUserDataFeed);
    } catch (Exception e) {
        e.printStackTrace();
        // handle exception
    }
    return channel;
}

Jetzt benötigen Sie einen UserNotificationChannel-Verweis in mNotificationChannel.

Erstellen eines UserNotificationReader, um eingehende UserNotifications zu empfangen und auf den UserNotification-Verlauf zuzugreifen

Wie bereits gezeigt, fungiert die anfängliche Google Cloud Messaging-Benachrichtigung lediglich als Signal. Sie müssen diese Signalnutzlast an die Plattform für verbundene Geräte übergeben, damit das SDK eine vollständige Synchronisierung mit dem Server der Plattform für verbundene Geräte, die sämtliche vom App-Server veröffentlichten UserNotifications enthält, ausführt. Dadurch wird die vollständige Benachrichtigungsnutzlast, die vom App-Server veröffentlicht wurde und die dem Signal entspricht, abgerufen (und falls vorherige Benachrichtigungen veröffentlicht, jedoch aufgrund von Geräteverbindungsproblemen oder anderen Problemen nicht im App-Client empfangen wurden, werden diese ebenfalls abgerufen). Durch diese Echtzeitsynchronisierungen, die kontinuierlich vom SDK ausgeführt werden, kann der App-Client auf den lokalen Cache des UserNotification-Datenfeeds des angemeldeten Benutzers zugreifen. In diesem Fall ermöglicht der UserNotificationReader den Zugriff des App-Clients auf den Datenfeed – um über einen Ereignislistener die neueste Benachrichtigungsnutzlast zu empfangen oder auf die UserNotification-Sammlung zuzugreifen, die als Ansichtsmodell für den Benachrichtigungsverlauf des Benutzers verwendet werden kann.

Empfangen von UserNotifications

Zunächst müssen Sie einen UserNotificationReader instanziieren und alle im Reader bereits vorhandenen UserNotifications abrufen, wenn Sie diese Informationen für die zu aktivierende Erfahrung verwenden möchten. Es ist immer davon ausgehen, dass der App-Server bereits Benachrichtigungen für den angemeldeten Benutzer veröffentlicht hat, da der betreffende Geräteendpunkt möglicherweise nicht der einzige oder nicht der erste Endpunkt ist, auf dem der Benutzer Ihre App installiert hat.

private static UserNotificationReader mReader;
private static final ArrayList<UserNotification> mHistoricalNotifications = new ArrayList<>();
// Instantiate UserNotificationReader
UserNotificationReaderOptions options = new UserNotificationReaderOptions();
mReader = mNotificationChannel.createReaderWithOptions(options);
// Read any previously published UserNotifications that have not expired yet
mReader.readBatchAsync(Long.MAX_VALUE).thenAccept(new AsyncOperation.ResultConsumer<UserNotification[]>() {
    @Override
    public void accept(UserNotification[] userNotifications) throws Throwable {
        synchronized (mHistoricalNotifications) {
            for (UserNotification notification : userNotifications) {
                if (notification.getReadState() == UserNotificationReadState.UNREAD) {
                    mHistoricalNotifications.add(notification);
                }
            }
        }
 
        if (RunnableManager.getHistoryUpdated() != null) {
            activity.runOnUiThread(RunnableManager.getHistoryUpdated());
        }
    }
});

Fügen Sie jetzt einen Ereignislistener hinzu, der ausgelöst wird, wenn die Plattform für verbundene Geräte eine Synchronisierung durchführt und Sie über neue Änderungen zu benachrichtigen hat. Im Fall von Graph-Benachrichtigungen kann es sich bei neuen Änderungen um neue eingehende UserNotifications handeln, die vom App-Server veröffentlicht wurden. Oder es kann sich um UserNotifcation-Aktualisierungen, -Löschungen oder abgelaufene UserNotifications vom Server oder von anderen registrierten Endpunkten handeln, bei denen derselbe Benutzer angemeldet ist.

Tipp

Im Ereignislistener behandeln Sie die Hauptgeschäftslogik und verwenden den Inhalt der Benachrichtigungsnutzlast auf Grundlage Ihrer Szenarien. Wenn Sie derzeit eine Google Cloud Messaging-Datennachricht verwenden, um eine visuelle Benachrichtigung im Infobereich auf Betriebssystemebene zu erstellen, oder wenn Sie mit dem Inhalt der Benachrichtigung Benutzeroberflächenelemente der App aktualisieren, führen Sie dies hier durch.

mReader.addDataChangedListener(new EventListener<UserNotificationReader, Void>() {
    @Override
    public void onEvent(UserNotificationReader userNotificationReader, Void aVoid) {
        userNotificationReader.readBatchAsync(Long.MAX_VALUE).thenAccept(new AsyncOperation.ResultConsumer<UserNotification[]>() {
        @Override
        public void accept(UserNotification[] userNotifications) throws Throwable {
            boolean updatedNew = false;
            boolean updatedHistorical = false;
            synchronized (sHistoricalNotifications) {
                for (final UserNotification notification : userNotifications) {
                    if (notification.getStatus() == UserNotificationStatus.ACTIVE && notification.getReadState() == UserNotificationReadState.UNREAD) {
                        switch (notification.getUserActionState()) {
                            case NO_INTERACTION:
                                // Brand new notification
                                // Insert business logic to construct a new visual notification in Android notification tray for the user to see
                                // ...
                            case DISMISSED:
                                // Existing notification that is marked as dismissed
                                // An app client receive this type of changes because another app client logged in by the same user has marked the notification as dismissed and the change is fanned-out to everywhere
                                // This state sync across app clients on different devices enable universal dismiss of notifications and other scenarios across multiple devices owned by the same user
                                // Insert business logic to dismiss the corresponding visual notification inside Android system notification tray, to make sure users don’t have to deal with redundant information across devices, and potentially insert this notification in your app’s notification history view
                                // ...
                            default:
                                // Unexpected
                        }
                    } else {
                        // ...
                    }
                }
            }
        }
    });
}
});

Aktualisieren des Status einer vorhandenen UserNotification

Im vorherigen Abschnitt wurde erwähnt, dass manchmal eine über den Reader empfangene UserNotification-Änderung eine Statusaktualisierung einer vorhandenen UserNotification sein kann, die als verworfen oder gelesen markiert ist. In diesem Fall kann der App-Client auswählen, wie vorzugehen ist, z.B. Aktivieren von universellem Schließen, indem die entsprechende visuelle Benachrichtigung auf dem betreffenden Gerät entfernt wird. Häufig wurde die UserNotification-Änderung zuvor von Ihrem App-Client initiiert – von einem anderen Gerät aus. Sie können die Zeit der Statusaktualisierung der UserNotifications wählen. In der Regel erfolgt diese jedoch, wenn die entsprechende visuelle Benachrichtigung durch den Benutzer des Geräts behandelt wird. Oder die Benachrichtigung wird vom Benutzer in einer von Ihnen aktivierten In-App-Erfahrung behandelt. Ein Beispiel für diesen Flow wäre etwa: Der App-Server veröffentlicht eine Benachrichtigung an Benutzer A. Benutzer A empfängt diese Benachrichtigung auf seinem PC und seinem Smartphone, auf denen die App-Clients installiert sind. Der Benutzer klickt auf dem PC auf die Benachrichtigung und öffnet die App, um die entsprechende Aufgabe zu behandeln. Der App-Client auf dem PC ruft dann das SDK der Plattform für verbundene Geräte auf, um den Status der entsprechenden Benutzerbenachrichtigung zu aktualisieren, damit diese Aktualisierung auf allen Geräten des Benutzers synchronisiert wird. Die anderen App-Clients, entfernen dann bei Empfang dieser Statusaktualisierung in Echtzeit die entsprechende visuelle Warnung/Nachricht/Popupbenachrichtigung aus der Mitteilungszentrale/dem Infobereich/dem Info-Center des Geräts. So werden Benachrichtigungen auf den Geräten eines Benutzers universell geschlossen.

Tipp

Die UserNotification-Klasse bietet derzeit 2 Typen von Statusaktualisierungen – Sie können den UserNotificationReadState oder den UserNotificationUserActionState ändern und eine eigene Logik für die Vorgehensweise definieren, die beim Aktualisieren von Benachrichtigungen angewendet werden soll. Sie können z.B. den UserActionState als „Activated“ oder „Dismissed“ markieren und dann anhand dieses Werts universelles Verfwerfen implementieren. Alternativ oder gleichzeitig können Sie den ReadState als „Read“ oder „Unread“ markieren und auf dieser Grundlage bestimmen, welche Benachrichtigungen im App-internen Benachrichtigungsverlauf angezeigt werden sollen. Im folgenden Codeausschnitt wird gezeigt, wie der UserNotificationUserActionState einer Benachrichtigung als „Dismissed“ markiert wird.

public void dismissNotification(int position) {
    final UserNotification notification = mNewNotifications.get(position);
          
    notification.setUserActionState(UserNotificationUserActionState.DISMISSED);
    notification.saveAsync();
}