Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Действия пользователей — это конструкции данных, представляющие задачи пользователя в приложении. Они позволяют сохранить моментальный снимок задачи для продолжения позже. Функция временной шкалы Windows представляет пользователей Windows с прокручиваемым списком всех последних действий, представленных как карточки с текстом и графикой. Дополнительные сведения о действиях пользователей в целом см. в разделе "Продолжить действия пользователей", даже на разных устройствах. Для получения рекомендаций по созданию или обновлению действий см. руководство Лучшие практики пользовательских действий.
С помощью пакета SDK Project Rome ваше приложение Android может не только публиковать пользовательские активности для использования в таких функциях Windows, как временная шкала, но и выступать в качестве конечной точки, считывая эти активности и предоставляя их пользователю, как это делает временная шкала на устройствах Windows. Это позволяет приложениям между устройствами преодолевать свои платформы и предоставлять возможности, которые следуют за пользователями, а не устройствами.
См. справочную страницу API для ссылок на справочные документы, относящиеся к этим сценариям.
На следующих шагах будут ссылаться на код из примера приложения Project Rome Android.
Для всех функций подключенных устройств вам потребуется интегрированная среда разработки приложений Android и устройство Android с одной из поддерживаемых архитектур (armeabi-v7a, arm64-v8a, x86 или x86_64) или эмулятор. Система должна работать под управлением Android 4.4.2 или более поздней версии.
Предварительная настройка платформы подключенных устройств и уведомлений
Перед реализацией удаленного подключения необходимо выполнить несколько шагов, чтобы предоставить приложению Android возможность подключения к удаленным устройствам, а также отправлять и получать уведомления.
Регистрация приложения
Аутентификация учетной записи Майкрософт (MSA) или Azure Active Directory (AAD) требуется почти для всех функций пакета SDK Project Rome (исключение составляют API для обмена с ближайшим окружением). Если у вас еще нет MSA и вы хотите использовать его, зарегистрируйтесь в account.microsoft.com.
Замечание
Учетные записи Azure Active Directory (AAD) не поддерживаются с API ретрансляции устройств.
Используя выбранный метод проверки подлинности, необходимо зарегистрировать приложение в Корпорации Майкрософт, следуя инструкциям на портале регистрации приложений. Если у вас нет учетной записи разработчика Майкрософт, необходимо создать ее.
При регистрации приложения с помощью MSA необходимо получить строку идентификатора клиента. Сохраните это для дальнейшего использования. Это позволит приложению получить доступ к ресурсам платформы подключенных устройств Майкрософт. Если вы используете AAD, ознакомьтесь с библиотеками проверки подлинности Azure Active Directory , чтобы получить строку идентификатора клиента.
Добавление пакета SDK
Вставьте следующие ссылки на репозиторий в файл build.gradle в корне проекта.
allprojects {
repositories {
jcenter()
}
}
Затем вставьте следующую зависимость в файл build.gradle , который находится в папке проекта.
dependencies {
...
implementation 'com.microsoft.connecteddevices:connecteddevices-sdk:+'
}
В файле AndroidManifest.xml вашего проекта добавьте следующие разрешения внутрь элемента <manifest>
(если они еще не присутствуют). Это дает приложению разрешение на подключение к Интернету и включение обнаружения Bluetooth на устройстве.
Обратите внимание, что разрешения, связанные с Bluetooth, необходимы только для использования обнаружения Bluetooth; Они не требуются для других функций платформы подключенных устройств. Кроме того, ACCESS_COARSE_LOCATION
требуется только в пакетах SDK для Android 21 и более поздних версий. В Android SDK 23 и более поздних версиях разработчик также должен предложить пользователю разрешить доступ к местоположению во время выполнения.
<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" />
Затем перейдите к классу(ам) активностей, где вы хотите, чтобы функции подключенных устройств находились. Импортируйте следующие пакеты.
import com.microsoft.connecteddevices;
import com.microsoft.connecteddevices.remotesystems;
import com.microsoft.connecteddevices.remotesystems.commanding;
Настройка проверки подлинности и управления учетными записями
Платформа подключенных устройств требует, чтобы действительный маркер OAuth использовался в процессе регистрации. Вы можете использовать предпочитаемый метод создания маркеров OAuth и управления ими. Однако, чтобы помочь разработчикам начать использовать платформу, мы включили провайдера аутентификации в виде части примера приложения Android, который создает токены обновления и управляет ими для вашего удобства.
Если вы хотите реализовать интерфейс ConnectedDevicesAccountManager самостоятельно, обратите внимание на следующие сведения:
Если вы используете MSA, вам потребуется включить в запрос входа следующие области: "wl.offline_access"
, "ccs.ReadWrite"
, "dds.read"
, "dds.register"
, "wns.connect"
, "asimovrome.telemetry"
и "https://activity.windows.com/UserActivity.ReadWrite.CreatedByApp"
.
Если вы используете учетную запись AAD, вам потребуется запросить следующие аудитории: "https://cdpcs.access.microsoft.com"
, "https://cs.dds.microsoft.com"
, "https://wns.windows.com/"
и "https://activity.microsoft.com"
.
Замечание
Учетные записи Azure Active Directory (AAD) не поддерживаются с API ретрансляции устройств.
Независимо от того, используете ли вы предоставленную реализацию ConnectedDevicesAccountManager или нет, если вы используете AAD, вам потребуется указать следующие разрешения для регистрации приложения на портале Azure (portal.azure.com > Azure Active Directory > регистрации приложений):
- Служба ленты активности Майкрософт
- Доставка и изменение уведомлений пользователей для этого приложения
- Чтение и запись действий приложений в вашем веб-канале активности
- Служба уведомлений Windows
- Подключение устройства к службе уведомлений Windows
- Служба каталогов устройств Майкрософт
- Просмотр списка устройств
- Добавление в список устройств и приложений
- Служба команд Майкрософт
- Обмен данными с устройствами пользователей
- Считывание списка устройств пользователя
Регистрация приложения для работы с push-уведомлениями
Зарегистрируйте приложение в службе поддержки Google для Firebase Cloud Messaging . Обязательно запишите полученный идентификатор отправителя и ключ сервера; Вам потребуется их позже.
После регистрации необходимо связать функции push-уведомлений с платформой подключенных устройств в приложении.
mNotificationRegistration = new ConnectedDevicesNotificationRegistration();
mNotificationRegistration.setType(ConnectedDevicesNotificationType.FCM);
mNotificationRegistration.setToken(token);
mNotificationRegistration.setAppId(Secrets.FCM_SENDER_ID);
mNotificationRegistration.setAppDisplayName("SampleApp");
Регистрация приложения в Центре разработки Microsoft Windows для взаимодействия с несколькими устройствами
Это важно
Этот шаг необходим только в том случае, если вы хотите использовать функции Project Rome для доступа к данным из или выполнения запросов устройств, отличных от Windows. Если вы используете только целевые устройства Windows, вам не нужно выполнить этот шаг.
Перейдите на панель мониторинга Центра разработки, перейдите к Функциям взаимодействия между устройствами из области навигации слева и выберите настройку нового приложения для нескольких устройств, как показано на изображении ниже.
Для процесса подключения центра разработки требуются следующие действия.
Выберите поддерживаемые платформы— выберите платформы, на которых ваше приложение будет иметь присутствие и включено для взаимодействия с несколькими устройствами. В случае интеграции с уведомлениями Graph можно выбрать из Windows, Android и (или) iOS.
Укажите идентификаторы приложений— предоставьте идентификаторы приложений для каждой платформы, в которой ваше приложение имеет присутствие. Для приложений Android это имя пакета, назначенное приложению при создании проекта. Имя пакета можно найти в консоли Firebase в разделе "Общие сведения> о проекте". Вы можете добавить разные идентификаторы (до десяти) на платформу— это в случае, если у вас есть несколько версий одного приложения или даже разных приложений, которые хотят иметь возможность получать те же уведомления, отправленные сервером приложений, предназначенным для одного пользователя.
Укажите или выберите идентификаторы приложений из регистрации приложений MSA и/или AAD. Эти идентификаторы клиентов, соответствующие регистрации приложений MSA или AAD, были получены в предыдущих шагах регистрации приложений MSA/AAD выше.
Уведомления Graph и другие возможности платформы подключенных устройств используют каждую из собственных платформ уведомлений на основных платформах для отправки уведомлений в конечные точки клиента приложения, а именно WNS (для Windows UWP), FCM (для Android) и APNS (для iOS). Предоставьте свои учетные данные для этих платформ уведомлений, чтобы включить Graph Notifications для доставки уведомлений вашему серверу приложений, когда вы публикуете уведомления, нацеленные на пользователя. Для Android включение службы Cloud Messaging является обязательным условием для использования уведомлений Microsoft Graph. Кроме того, обратите внимание, что обязательный идентификатор отправителя соответствует идентификатору отправителя Cloud Messaging Firebase, а ключ API соответствует ключу устаревшего сервера. Оба элемента можно найти в консоли Firebase — в разделе "Проект" — "Настройки" на вкладке Cloud Messaging, как показано на снимке экрана.
Последний шаг — проверить домен приложения между устройствами, который служит процессом проверки, чтобы доказать, что у вашего приложения есть владение этим доменом, который действует как удостоверение приложения между устройствами для зарегистрированного приложения.
Использование платформы
Создание платформы
Чтобы начать, просто инициализируйте платформу.
ConnectedDevicesPlatform sPlatform = new ConnectedDevicesPlatform(context);
Подписка на события ConnectedDevicesAccountManager для обработки учетной записи пользователя
Для доступа к платформе требуется прошедший проверку подлинности пользователь. Необходимо подписаться на события ConnectedDevicesAccountManager , чтобы убедиться, что используется допустимая учетная запись.
ConnectedDevicesPlatform sPlatform.getAccountManager().accessTokenRequested().subscribe((accountManager, args) -> {
// Get access token
}
ConnectedDevicesPlatform sPlatform.getAccountManager().accessTokenInvalidated().subscribe((accountManager, args) -> {
// Refresh and renew existing access token
}
Подписка на события ConnectedDevicesNotificationRegistrationManager
Аналогичным образом платформа использует уведомления для доставки команд между устройствами. Поэтому необходимо подписаться на события ConnectedDevicesNotificationRegistrationManager , чтобы убедиться, что состояния регистрации облака действительны для используемой учетной записи. Проверьте состояние с помощью ConnectedDevicesNotificationRegistrationState
ConnectedDevicesPlatform sPlatform.getNotificationRegistrationManager().notificationRegistrationStateChanged().subscribe((notificationRegistrationManager, args) -> {
// Check state using ConnectedDevicesNotificationRegistrationState enum
}
Запуск платформы
Теперь, когда платформа инициализирована, и обработчики событий готовы начать обнаружение удаленных системных устройств.
ConnectedDevicesPlatform sPlatform.start();
Получение учетных записей пользователей, известных приложению
Важно убедиться, что список учетных записей пользователей, известных приложению, правильно синхронизируется с ConnectedDevicesAccountManager.
Используйте ConnectedDevicesAccountManager.addAccountAsync , чтобы добавить новую учетную запись пользователя.
public synchronized AsyncOperation<ConnectedDevicesAddAccountResult> addAccountToAccountManagerAsync(ConnectedDevicesAccount account) {
return ConnectedDevicesPlatform sPlatform.getAccountManager().addAccountAsync(account);
}
Чтобы удалить недопустимую учетную запись, можно использовать ConnectedDevicesAccountManager.removeAccountAsync
public synchronized AsyncOperation<ConnectedDevicesAddAccountResult> removeAccountToAccountManagerAsync(ConnectedDevicesAccount account) {
return ConnectedDevicesPlatform sPlatform.getAccountManager().removeAccountAsync(account);
}
Инициализация канала действий пользователя
Чтобы реализовать функции активности пользователей в вашем приложении, сначала необходимо инициализировать поток активности пользователей, создав UserActivityChannel. Вы должны рассматривать это так, как шаг инициализации платформы выше: он должен быть проверен и, возможно, повторен всякий раз, когда приложение приходит на передний план (но не до инициализации платформы).
Вам также потребуется идентификатор кроссплатформенного приложения, который был получен через регистрацию панели мониторинга разработчика Майкрософт. Следующие методы инициализируют UserActivityChannel.
private UserActivityChannel mActivityChannel;
private UserDataFeed mUserDataFeed;
// ...
/**
* Initializes the UserActivityFeed.
*/
public void initializeUserActivityFeed() {
// define what scope of data this app needs
SyncScope[] scopes = { UserActivityChannel.getSyncScope(), 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
mActivityChannel = getUserActivityChannel();
}
// 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 UserActivityChannel getUserActivityChannel() {
UserActivityChannel channel = null;
try {
// create a UserActivityChannel for the signed in account
channel = new UserActivityChannel(mUserDataFeed);
} catch (Exception e) {
e.printStackTrace();
// handle exception
}
return channel;
}
На этом этапе у вас должна быть ссылка UserActivityChannel в mActivityChannel.
Создание и публикация действия пользователя
Затем задайте данные идентификатора, DisplayText и ActivationURI для нового UserActivity. Идентификатор должен быть уникальной строкой. DisplayText будет отображаться на других устройствах при просмотре действия (например, на временной шкале Windows), поэтому оно должно быть кратким описанием действия. ActivationUri определяет, какое действие выполняется при активации UserActivity (например, при выборе на временной шкале). Следующий код заполняет примеры данных для этих полей.
private UserActivity mActivity;
private String mActivityId;
private String mDisplayText;
private String mActivationUri;
// ...
mActivityId = UUID.randomUUID().toString();
mDisplayText = "Created by OneSDK Sample App";
mActivationUri = "http://contoso.com");
Затем укажите метод, создающий новый экземпляр UserActivity .
// Create the UserActivity (with unique ID) using a custom method.
mActivity = createUserActivity(mActivityChannel, mActivityId);
// ...
// Custom method for creating a new UserActivity
@Nullable
private UserActivity createUserActivity(UserActivityChannel channel, String activityId)
{
UserActivity activity = null;
AsyncOperation<UserActivity> activityOperation = channel.getOrCreateUserActivityAsync(activityId);
try {
activity = activityOperation.get();
Log.d("UserActivityFragment","Created user activity successfully");
} catch (Exception e) {
e.printStackTrace();
Log.d("UserActivityFragment","Created user activity successfully");
}
return activity;
}
После создания экземпляра UserActivity заполните его данными, определенными выше.
//set the properties of the UserActivity:
// Display Text will be shown when the UserActivity is viewed on other devices
mActivity.getVisualElements().setDisplayText(mDisplayText);
// ActivationURI will determine what is launched when your UserActivity is activated from other devices
mActivity.setActivationUri(mActivationUri);
Наконец, опубликуйте действие в облаке.
// This code saves and publishes the activity
AsyncOperation<Void> operation = mActivity.saveAsync();
operation.whenCompleteAsync(new AsyncOperation.ResultBiConsumer<Void, Throwable>() {
@Override
public void accept(Void aVoid, Throwable throwable) throws Throwable {
if (throwable != null)
{
Log.d("UserActivityFragment", "Failed to save");
} else {
Log.d("UserActivityFragment", "User activity saved");
}
}
});
Подсказка
Помимо описанных выше свойств, можно настроить множество других функций. Полный обзор различных способов настройки UserActivity смотрите в классах UserActivity, UserActivityVisualElements и UserActivityAttribution. Дополнительные рекомендации по проектированию действий пользователей см. в руководстве по действиям пользователей .
Обновление существующего действия пользователя
Если у вас есть существующее действие и хотите обновить ее сведения (в случае нового взаимодействия, измененной страницы и т. д.), это можно сделать с помощью UserActivitySession.
private UserActivitySession mActivitySession;
// ...
if (mActivity != null)
{
// create a session from a previous UserActivity instance.
mActivitySession = mActivity.createSession();
Log.d("UserActivityFragment", "Starting");
}
После создания сеанса приложение может внести любые необходимые изменения в свойства UserActivity. После внесения изменений закройте сеанс.
mActivitySession.close();
mActivitySession = null;
Log.d("UserActivityFragment", "Stopping");
UserActivitySession можно рассматривать как способ создания userActivitySessionHistoryItem (описано в следующем разделе). Вместо создания нового userActivity каждый раз, когда пользователь переходит на новую страницу, можно просто создать новый сеанс для каждой страницы. Это обеспечит более интуитивно понятный и упорядоченный опыт чтения действий.
Чтение действий пользователей
Ваше приложение может читать действия пользователей и представлять их пользователю так же, как функция временной шкалы Windows. Чтобы настроить чтение действий пользователей, используйте тот же экземпляр UserActivityChannel , который использовался ранее. Этот экземпляр может предоставлять экземпляры UserActivitySessionHistoryItem, которые отражают участие пользователя в конкретной активности в течение определенного периода времени.
private ArrayList<UserActivitySessionHistoryItem> mHistoryItems;
// ...
mHistoryItems.clear();
Log.d("UserActivityFragment", "Read");
//Async method to read activities. Last (most recent) 5 activities will be returned
AsyncOperation<UserActivitySessionHistoryItem[]> operation = mActivityChannel.getRecentUserActivitiesAsync(5);
operation.whenCompleteAsync(new AsyncOperation.ResultBiConsumer<UserActivitySessionHistoryItem[], Throwable>() {
@Override
public void accept(UserActivitySessionHistoryItem[] result, Throwable throwable) throws Throwable {
if (throwable != null)
{
Log.d("UserActivityFragment", "Failed to read user activity!" + throwable.getMessage() + " " + throwable.getStackTrace());
} else {
// get the returned UserActivitySessionHistoryItems
for (UserActivitySessionHistoryItem item : result)
{
mHistoryItems.add(item);
}
}
}
});
Теперь приложение должно содержать заполненный список UserActivitySessionHistoryItem. Каждое из них может доставлять базовую пользовательную активность (дополнительные сведения см. в разделе UserActivitySessionHistoryItem ), которое можно отобразить пользователю.