Пользователи часто начинают работу на телефоне Android, например просматривают документ, сортируют сообщения или выбирают товары, а затем хотят продолжить на Googlebook с его большим экраном, физической клавиатурой и многооконным рабочим пространством.
Функция Продолжить на другом устройстве в Android 17 (уровень API 37) и более поздних версиях позволяет панели задач Googlebook показывать значок приложения (подсказку) для действия, которое пользователь выполняет на своем телефоне, находящемся рядом. Пользователи могут продолжить работу на Googlebook одним нажатием.
Благодаря передаче данных между устройствами пользователь может продолжить работу с того места, на котором остановился на телефоне, в адаптивном приложении для Android или в браузере для компьютера.
Как выбрать поток передачи
Прежде чем включить передачу данных между устройствами, решите, как будет открываться каждое действие в приложении на телефоне, когда пользователь выберет предложение "Продолжить на устройстве" на Googlebook:
| Процесс передачи запроса | Целевой уровень в Googlebook | Поддерживаемые устройства | Key API |
|---|---|---|---|
| Передача данных между приложениями | Нативное приложение Android, запущенное в окне на компьютере | Приложения, оптимизированные для больших экранов и многооконного режима на компьютере, в Google Play | HandoffActivityData.Builder |
| Передача данных между приложениями с переходом на сайт | Нативное приложение Android, если оно установлено, или URL в браузере по умолчанию на компьютере. | Приложения, оптимизированные для работы в собственном окне на компьютере, но требующие надежного браузера в качестве резервного варианта, если приложение не установлено на устройстве Chromebook. | setFallbackUri |
| Переход на сайт | URL в браузере для компьютера по умолчанию (или перехваченный нативным приложением, если для него настроены ссылки на приложения для Android) | Рабочие процессы, в которых веб-приложение является основным интерфейсом для компьютеров | HandoffActivityData.createWebHandoff |
Как включить передачу для действия
Функция "Продолжить на другом устройстве" отключена по умолчанию и настраивается для каждого действия отдельно. Выполните следующие действия при каждой отправке на телефоне:
- Вызовите
setHandoffEnabledи передайтеtrue, когда операция загрузит состояние, необходимое для передачи. После включения этой функции система может запрашивать данные для передачи, когда действие выполняется в активном режиме или переходит в фоновый. - Переопределите
onHandoffActivityDataRequested, чтобы возвращать ненулевой объектHandoffActivityData. Вы можете в любое время запроситьisHandoffEnabled, чтобы проверить, активна ли передача для действия.
import android.app.Activity
import android.app.HandoffActivityData
import android.app.HandoffActivityDataRequestInfo
import android.os.Bundle
import android.os.PersistableBundle
class DocumentEditorActivity : Activity() {
private var documentId: String = "doc_42"
private var scrollOffsetPx: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Enable handoff once the activity is ready to transfer state.
setHandoffEnabled(true, null)
}
override fun onHandoffActivityDataRequested(
handoffRequestInfo: HandoffActivityDataRequestInfo
): HandoffActivityData {
val extras = PersistableBundle().apply {
putString(EXTRA_DOCUMENT_ID, documentId)
putInt(EXTRA_SCROLL_OFFSET, scrollOffsetPx)
}
return HandoffActivityData.Builder(getComponentName())
.setExtras(extras)
.build()
}
companion object {
const val EXTRA_DOCUMENT_ID = "extra_document_id"
const val EXTRA_SCROLL_OFFSET = "extra_scroll_offset"
}
}
Статус передачи посылки
Система вызывает onHandoffActivityDataRequested в двух случаях:
- Передача активного приложения. Приложение работает на телефоне в активном режиме, и пользователь запускает передачу с панели задач Googlebook.
- Переход в фоновый режим. Активность переходит в фоновый режим на телефоне, и система кеширует полезную нагрузку передачи на случай, если пользователь позже выберет подсказку в Google Книгах.
Как проверить, активен ли запрос на передачу
Проверьте HandoffActivityDataRequestInfo с помощью isActiveRequest, чтобы отличить активную передачу, инициированную пользователем, от сохранения в фоновом режиме:
- Если
isActiveRequestвозвращает значениеtrue, пользователь активно запросил продолжение на другом устройстве, пока действие видно. - Если
isActiveRequestвозвращаетfalse, система кэширует состояние, когда операция останавливается.
Если на телефоне показывается визуальный индикатор, подтверждающий, что задача переносится на Googlebook, запланируйте обновление интерфейса асинхронно, чтобы onHandoffActivityDataRequested возвращало значение без задержки.
Как прикрепить дополнительные данные о состоянии и резервную веб-страницу
Полезная нагрузка HandoffActivityData содержит следующие сведения:
- Целевой компонент (обязательный параметр для передачи данных между приложениями): передайте
this.getComponentName()(ComponentNameдействия) или явныйComponentName(this, TargetActivity::class.java)вHandoffActivityData.Builder, чтобы указать, какое действие будет запущено в Google Книгах. - Дополнительные параметры (необязательно). Передайте
PersistableBundleвsetExtras(), содержащий идентификаторы и координаты интерфейса (например, идентификаторы открытых документов, ключи активных вкладок или позиции прокрутки). Размер пакета должен быть меньше 50 КБ. - Резервный URI (необязательно). Передайте веб-
UriвsetFallbackUri, чтобы Googlebook мог открыть задачу в браузере по умолчанию, если ваше приложение Android не установлено.
import android.app.Activity
import android.app.HandoffActivityData
import android.app.HandoffActivityDataRequestInfo
import android.app.HandoffActivityParams
import android.net.Uri
import android.os.Bundle
import android.os.PersistableBundle
class ArticleReaderActivity : Activity() {
private var articleId: String = "android-desktop-windowing"
private var readingProgressPercent: Int = 45
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHandoffEnabled(
true,
HandoffActivityParams.Builder()
.setAllowHandoffWithoutPackageInstalled(true)
.build()
)
}
override fun onHandoffActivityDataRequested(
handoffRequestInfo: HandoffActivityDataRequestInfo
): HandoffActivityData {
if (handoffRequestInfo.isActiveRequest()) {
window.decorView.post {
onHandoffStartedToSecondaryDevice()
}
}
val extras = PersistableBundle().apply {
putString(EXTRA_ARTICLE_ID, articleId)
putInt(EXTRA_READING_PROGRESS, readingProgressPercent)
}
val fallbackWebUri = Uri.Builder()
.scheme("https")
.authority("example.com")
.appendPath("articles")
.appendPath(articleId)
.appendQueryParameter("progress", readingProgressPercent.toString())
.build()
return HandoffActivityData.Builder(getComponentName())
.setExtras(extras)
.setFallbackUri(fallbackWebUri)
.build()
}
private fun onHandoffStartedToSecondaryDevice() {
// Save local drafts and update phone UI without blocking handoff.
}
companion object {
const val EXTRA_ARTICLE_ID = "extra_article_id"
const val EXTRA_READING_PROGRESS = "extra_reading_progress"
}
}
Как настроить передачу в веб-интерфейс
Если основное приложение для компьютеров на Googlebook – это веб-приложение, передайте HandoffActivityParams с setAllowHandoffWithoutPackageInstalled(true) в setHandoffEnabled и вызовите HandoffActivityData.createWebHandoff вместо HandoffActivityData.Builder:
import android.app.Activity
import android.app.HandoffActivityData
import android.app.HandoffActivityDataRequestInfo
import android.app.HandoffActivityParams
import android.net.Uri
import android.os.Bundle
class WebDashboardActivity : Activity() {
private var projectId: String = "proj_901"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHandoffEnabled(
true,
HandoffActivityParams.Builder()
.setAllowHandoffWithoutPackageInstalled(true)
.build()
)
}
override fun onHandoffActivityDataRequested(
handoffRequestInfo: HandoffActivityDataRequestInfo
): HandoffActivityData {
val webUri = Uri.Builder()
.scheme("https")
.authority("app.example.com")
.appendPath("projects")
.appendPath(projectId)
.build()
return HandoffActivityData.createWebHandoff(webUri)
}
}
Как получать и восстанавливать состояние на устройстве Googlebook
Когда пользователь выбирает вариант "Продолжить на устройстве" на панели задач Googlebook, система запускает целевое приложение ComponentName в окне на рабочем столе и добавляет дополнительные данные PersistableBundle к запуску Intent.
На Googlebook при обработке входящей передачи учитывайте многооконный режим и многопанельные макеты:
- Извлеките дополнительные данные, переданные при переходе. В методах
onCreateиonNewIntentпринимающего класса activity извлеките дополнительные данные из входящего объектаIntent. ОбработкаonNewIntentгарантирует, что если ваше действие использует режим запускаsingleTopили переходит к существующему окну в многооконном режиме, окно обновится до переданного элемента. - Адаптируйте состояние для многопанельных макетов. Состояние, которое занимало полноэкранный режим на телефоне, часто сопоставляется с выбранным элементом в макете "список и подробные сведения" или вспомогательной панели на Googlebook. Заполните основной список и панель подробностей, чтобы в многооконном режиме была вся необходимая информация.
- Сохраняйте восстановленное состояние при изменении размера окна. Храните переданное состояние в
ViewModel(SavedStateHandle) илиrememberSaveableв Jetpack Compose, чтобы при изменении размера окна в свободной форме на устройстве Googlebook восстановленный сеанс не сбрасывался.
import android.app.Activity
import android.content.Intent
import android.os.Bundle
class DocumentEditorReceiverActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Restore from the handoff intent only on initial launch so subsequent
// desktop window configuration changes use saved instance state.
if (savedInstanceState == null) {
handleHandoffIntent(intent)
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
handleHandoffIntent(intent)
}
private fun handleHandoffIntent(incomingIntent: Intent?) {
val documentId = incomingIntent?.getStringExtra(EXTRA_DOCUMENT_ID)
?: return
val scrollOffsetPx = incomingIntent.getIntExtra(EXTRA_SCROLL_OFFSET, 0)
openDocumentInDesktopWorkspace(
documentId = documentId,
initialScrollOffsetPx = scrollOffsetPx
)
}
private fun openDocumentInDesktopWorkspace(
documentId: String,
initialScrollOffsetPx: Int
) {
// Load the document into the list-detail layout and restore scroll position.
}
companion object {
const val EXTRA_DOCUMENT_ID = "extra_document_id"
const val EXTRA_SCROLL_OFFSET = "extra_scroll_offset"
}
}
Как проверить синхронизацию задач между телефоном и Googlebook
Чтобы проверить реализацию:
- Подготовьте оба устройства
- Войдите в один и тот же аккаунт Google на телефоне Android (с Android 17 или более поздней версии) и Googlebook (или тестовом устройстве, работающем в многооконном режиме).
- Включите Bluetooth и подключите оба устройства к одной сети Wi-Fi.
- На обоих устройствах откройте Настройки > Подключенные устройства > Настройки подключения > Сервисы для нескольких устройств > Продолжение работы, следуйте инструкциям и включите Задачи. Полный список требований к среде приведен в разделе Настройка и тестирование.
- Как установить приложение
- Чтобы проверить передачу данных между приложениями, установите сборку на телефон и Googlebook.
- Для перехода на сайт или прямой передачи на сайт установите сборку на телефон и оставьте приложение неустановленным на Googlebook, чтобы убедиться, что браузер открывает нужный URL.
- Как запустить передачу
- На телефоне откройте приложение и перейдите к действию, которое позволяет передавать данные (вызов
setHandoffEnabled(true, null)для передачи данных между приложениями или передачаHandoffActivityParamsсsetAllowHandoffWithoutPackageInstalled(true)при тестировании с удаленным на Googlebook приложением). - На панели задач Googlebook найдите значок приложения с бейджем "Продолжить на" и нажмите на него.
- На телефоне откройте приложение и перейдите к действию, которое позволяет передавать данные (вызов
- Как проверить восстановление рабочего стола
- Убедитесь, что приложение открывается в окне на компьютере (или вкладке браузера) на том же элементе и в том же месте, что и на телефоне.
- Измените размер окна приложения на Googlebook и убедитесь, что восстановленный контент и выделение сохраняются при переходе между классами размеров окон.
Дополнительные ресурсы
- Как создавать адаптивные приложения для Googlebook
- Функция "Продолжить на устройстве"
- Как включить и настроить передачу данных между устройствами
- Сохранение состояния интерфейса