משתמשים מתחילים לעיתים קרובות משימות בטלפון Android שלהם – כמו בדיקת מסמך, מיון הודעות או עיון במגוון פריטים – ואז רוצים לעבור ל-Googlebook עם המסך הגדול יותר, המקלדת הפיזית וסביבת העבודה עם חלונות מרובים.
התכונה המשך ב-Android 17 (רמת API 37) ומעלה מאפשרת להציג בסרגל המשימות של Googlebook סמל האפליקציה (שנקרא הצעה) לפעילות שהמשתמש הפעיל בטלפון שנמצא בקרבת מקום. בלחיצה אחת, המשתמשים יכולים להמשיך את הפעילות שלהם ב-Googlebook.
הטמעה של העברת פעילות מקושרת למכשיר אחר מאפשרת לאפליקציה להעביר את הקשר הפעילות, כך שהמשתמש יכול להמשיך את תהליך העבודה שלו, באפליקציית Android המותאמת או בדפדפן במחשב, בדיוק מהמקום שבו הוא הפסיק בטלפון.
בחירת תהליך העברה
לפני שמפעילים את התכונה 'העברה בין מכשירים', צריך להחליט איך כל פעילות באפליקציית הטלפון תיפתח כשמשתמש יבחר בהצעה 'המשך במחשב' ב-Googlebook:
| תהליך העברה | טירגוט ב-Googlebook | מתאים לצפייה ב: | Key API |
|---|---|---|---|
| העברה מאפליקציה לאפליקציה | אפליקציית Android מקורית שפועלת בחלון במחשב | אפליקציות שעברו אופטימיזציה למסכים גדולים ולממשק מחשב ב-Google Play | HandoffActivityData.Builder |
| העברה מאפליקציה לאפליקציה עם חזרה לאתר | אפליקציית Android מקורית אם היא מותקנת, אחרת כתובת URL בדפדפן ברירת המחדל במחשב | אפליקציות שעברו אופטימיזציה לחוויית שימוש בחלון מקורי במחשב, אבל נדרשת חלופה אמינה בדפדפן אם האפליקציה לא מותקנת ב-Chromebook | setFallbackUri |
| העברה ישירה לאינטרנט | כתובת URL בדפדפן ברירת המחדל במחשב (או שכתובת ה-URL נחטפת על ידי אפליקציית הנייטיב אם היא מוגדרת לAndroid App Links) | תהליכי עבודה שבהם אפליקציית האינטרנט היא חוויית השימוש העיקרית במחשב | HandoffActivityData.createWebHandoff |
הפעלת העברה חלקה של פעילות
ההגדרה 'המשך הפעילות' מושבתת כברירת מחדל ומוגדרת לכל פעילות. פועלים לפי השלבים הבאים בכל פעילות שליחה בטלפון:
- מתקשרים אל
setHandoffEnabledומעבירים אתtrueאחרי שהפעילות טענה את המצב שנדרש להעברה. אחרי ההפעלה, המערכת יכולה לבקש נתוני העברה בזמן שהפעילות בחזית או עוברת לרקע. - מחליפים את
onHandoffActivityDataRequestedכדי להחזיר אובייקטHandoffActivityDataשאינו null. אפשר לשלוח שאילתה אל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.
- תיעוד של מצב הרקע: הפעילות עוברת לרקע בטלפון, והמערכת שומרת במטמון את נתוני ההעברה למקרה שהמשתמש יבחר בהצעה ב-Googlebook מאוחר יותר.
בדיקה אם בקשת ההעברה פעילה
בודקים את HandoffActivityDataRequestInfo באמצעות isActiveRequest כדי להבחין בין העברה פעילה שמתבצעת על ידי המשתמש לבין שמירה ברקע:
- אם הפונקציה
isActiveRequestמחזירהtrue, המשתמש ביקש באופן פעיל להמשיך במכשיר אחר בזמן שהפעילות גלויה. - אם הפונקציה
isActiveRequestמחזירהfalse, המערכת שומרת את המצב במטמון כשהפעילות נפסקת.
אם אתם מציגים בטלפון אינדיקטור ויזואלי שמאשר שהמשימה עוברת ל-Googlebook, כדאי לתזמן את עדכון ממשק המשתמש באופן אסינכרוני כדי שהפונקציה onHandoffActivityDataRequested תחזיר ערך ללא עיכוב.
צירוף תוספים של מצב וגיבוי לאינטרנט
מטען ייעודי (payload) מסוג HandoffActivityData מכיל את הפרטים הבאים:
- רכיב היעד (נדרש להעברה מאפליקציה לאפליקציה): מעבירים
this.getComponentName()(ה-ComponentNameשל הפעילות) אוComponentName(this, TargetActivity::class.java)מפורש אלHandoffActivityData.Builderכדי לציין איזו פעילות מופעלת ב-Googlebook. - Extras (אופציונלי): מעבירים
PersistableBundleאלsetExtras()שמכיל מזהים וקואורדינטות של ממשק המשתמש (לדוגמה, מזהי מסמכים פתוחים, מפתחות של כרטיסיות פעילות או מיקומי גלילה). גודל החבילה צריך להיות קטן מ-50KB. - Fallback 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של הפעילות המקבלת, מאחזרים את הנתונים הנוספים מה-Intentהנכנס. הטיפולonNewIntentמבטיח שאם הפעילות שלכם משתמשת במצבsingleToplaunch או מנותבת לחלון קיים בשולחן העבודה, החלון מתעדכן לפריט שהועבר. - התאמת המצב לפריסות מרובות חלוניות: מצב שתפס תצוגת פרטים במסך מלא בטלפון ממופה לרוב לפריט שנבחר בתוך פריסת רשימה-פרטים או חלונית תומכת ב-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.
- בכל אחד מהמכשירים, פותחים את ההגדרות > מכשירים מחוברים > העדפות חיבור > שירותים מרכזיים למכשירים שלך > המשך הפעילות, פועלים לפי ההנחיות להגדרה ומפעילים את משימות. במאמר הגדרה ובדיקה מפורטים כל התנאים המוקדמים לסביבה.
- התקנת האפליקציה
- כדי להשתמש בהעברה מאפליקציה לאפליקציה, צריך להתקין את ה-build גם בטלפון וגם ב-Googlebook.
- כדי להשתמש במעבר לגיבוי אינטרנטי או בהעברה ישירה לאינטרנט, צריך להתקין את הגרסה בטלפון ולהשאיר את האפליקציה לא מותקנת ב-Googlebook כדי לוודא שהדפדפן פותח את כתובת אתר צפויה.
- הפעלת ההעברה
- בטלפון, פותחים את האפליקציה ועוברים לפעילות שמאפשרת העברה (מתקשרים אל
setHandoffEnabled(true, null)להעברה מאפליקציה לאפליקציה, או מעביריםHandoffActivityParamsעםsetAllowHandoffWithoutPackageInstalled(true)כשבודקים כשהאפליקציה לא מותקנת ב-Googlebook). - ב-Googlebook, מחפשים את סמל האפליקציה בצד שמאל של סרגל האפליקציות עם התג 'המשך' ולוחצים עליו.
- בטלפון, פותחים את האפליקציה ועוברים לפעילות שמאפשרת העברה (מתקשרים אל
- אימות השחזור של שולחן העבודה
- מוודאים שהאפליקציה נפתחת בחלון במחשב (או בכרטיסיית דפדפן) בפריט המדויק ובמיקום הגלילה המדויק מתוך הטלפון.
- משנים את הגודל של חלון האפליקציה ב-Googlebook ומוודאים שהתוכן והבחירה ששוחזרו נשמרים גם כשעוברים בין גדלים שונים של חלונות.
מקורות מידע נוספים
- פיתוח אפליקציות אדפטיביות ל-Googlebook
- מידע על התכונה 'המשך הפעולה במכשיר אחר'
- הפעלה והתאמה אישית של העברת נתונים מקושרת למכשיר אחר
- שמירת מצבי ממשק המשתמש