לעתים קרובות משתמשים במכשירי Wear OS לחוויות שימוש ארוכות, כמו מעקב אחרי אימון. הדבר הזה יוצר בעיה בחוויית המשתמש: אם משתמש מתחיל משימה ואז עובר למסך השעון, איך הוא יכול לחזור למשימה? החזרה לאפליקציה באמצעות מרכז האפליקציות יכולה להיות קשה, במיוחד כשנמצאים בתנועה, ויוצרת חיכוך מיותר.
הפתרון הוא לשייך התראה מתמשכת לOngoingActivity
.
ההרשאה הזו מאפשרת למכשיר להציג מידע על פעילות שמתבצעת לאורך זמן בממשק המשתמש, ומאפשרת להשתמש בתכונות כמו הסמל שאפשר להקיש עליו בחלק התחתון של תצוגת השעון. כך המשתמשים יודעים על המשימה שפועלת ברקע, ויכולים לחזור לאפליקציה בלחיצה אחת.
לדוגמה, באפליקציית האימונים הזו, המידע יכול להופיע בלוח השעון של המשתמש כסמל של ריצה שאפשר להקיש עליו:
איור 1. אינדיקטור של פעילות.
התראה מתמשכת מציגה גם מידע בקטע האפליקציות שהיו בשימוש בזמן האחרון במרכז האפליקציות הגלובלי. כך המשתמשים יכולים לראות את הסטטוס של המשימה שלהם במקום נוח נוסף ולחזור לאפליקציה:
איור 2. מרכז האפליקציות הגלובלי.
אלה כמה דוגמאות למצבים שבהם כדאי להשתמש בהתראה מתמשכת שקשורה לפעילות מתמשכת:
איור 3. טיימר: סופר לאחור את הזמן ומסתיים כשהטיימר מושהה או מופסק.
איור 4. מסלול מפורט: הכרזה על הוראות הגעה ליעד. השיתוף מסתיים כשהמשתמש מגיע ליעד או מפסיק את הניווט.
איור 5. מדיה: השמעת מוזיקה לאורך הסשן. הסשן מסתיים מיד אחרי שהמשתמש משהה אותו.
ב-Wear, פעילויות מתמשכות נוצרות באופן אוטומטי לאפליקציות מדיה.
ב-codelab בנושא פעילות מתמשכת יש דוגמה מפורטת ליצירת פעילויות מתמשכות לסוגים אחרים של אפליקציות.
הגדרה
כדי להתחיל להשתמש ב-Ongoing Activity API באפליקציה, מוסיפים את התלויות הבאות לקובץ build.gradle
של האפליקציה:
dependencies {
implementation "androidx.wear:wear-ongoing:1.1.0"
implementation "androidx.core:core:1.17.0"
}
יצירת פעילות מתמשכת
התהליך כולל שלושה שלבים:
- יוצרים
NotificationCompat.Builder
רגיל ומגדירים אותו כמתמשך. - יוצרים ומגדירים אובייקט
OngoingActivity
ומעבירים אליו את כלי בניית ההתראות. - מחילים את הפעילות המתמשכת על כלי בניית ההתראות ומפרסמים את ההתראה שנוצרת.
יצירה והגדרה של ההתראה
קודם כל יוצרים NotificationCompat.Builder
. השלב העיקרי הוא לקרוא ל-setOngoing(true)
כדי לסמן אותה כהתראה פעילה. בשלב הזה אפשר גם להגדיר מאפיינים אחרים של ההתראה, כמו הסמל הקטן והקטגוריה.
// Create a PendingIntent to pass to the notification builder val pendingIntent = PendingIntent.getActivity( this, 0, Intent(this, AlwaysOnActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_SINGLE_TOP }, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, ) val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Always On Service") .setContentText("Service is running in background") .setSmallIcon(R.drawable.animated_walk) // Category helps the system prioritize the ongoing activity .setCategory(NotificationCompat.CATEGORY_WORKOUT) .setContentIntent(pendingIntent) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setOngoing(true) // Important!
יצירת OngoingActivity
לאחר מכן, יוצרים מופע של OngoingActivity
באמצעות כלי הבנייה שלו. הפונקציה
OngoingActivity.Builder
דורשת Context
, מזהה התראה ו-NotificationCompat.Builder
שיצרתם בשלב הקודם.
מגדירים את מאפייני המפתח שיוצגו בממשק המשתמש החדש:
- סמלים עם אנימציה וסמלים סטטיים: צריך לספק סמלים שמוצגים בלוח השעון במצבים פעיל וסביבתי.
- הקשה על סמל הפעילות:
PendingIntent
שמחזיר את המשתמש לאפליקציה שלכם כשהוא מקיש על סמל הפעילות המתמשכת. אפשר להשתמש שוב ב-pendingIndent
שנוצר בשלב הקודם.
val ongoingActivity = OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder) // Sets the icon that appears on the watch face in active mode. .setAnimatedIcon(R.drawable.animated_walk) // Sets the icon that appears on the watch face in ambient mode. .setStaticIcon(R.drawable.ic_walk) // Sets the tap target to bring the user back to the app. .setTouchIntent(pendingIntent) .build()
החלת ההגדרה על ההתראה ועל הפוסט
השלב האחרון הוא לקשר את OngoingActivity
להתראה ואז לפרסם אותה. השיטה ongoingActivity.apply()
משנה את הכלי המקורי ליצירת הודעות, ומוסיפה את הנתונים הנדרשים כדי שהמערכת תוכל להציג אותם במשטחים הנוספים. אחרי שמחילים את ההמלצה, אפשר ליצור ולפרסם את ההתראה כרגיל.
// This call modifies notificationBuilder to include the ongoing activity data. ongoingActivity.apply(applicationContext) // Post the notification. startForeground(NOTIFICATION_ID, notificationBuilder.build())
הוספת טקסט סטטוס דינמי למרכז האפליקציות
הקוד שלמעלה מוסיף את הסמל שאפשר להקיש עליו לתצוגת השעון. כדי לספק עדכונים עשירים יותר בזמן אמת בקטע האחרונים של מרכז האפליקציות, צריך ליצור אובייקט Status
ולצרף אותו ל-OngoingActivity
. אם לא מציינים Status
מותאם אישית, המערכת משתמשת כברירת מחדל בטקסט התוכן של ההתראה (מוגדר באמצעות setContentText()
).
כדי להציג טקסט דינמי, משתמשים בתג Status.Builder
. אפשר להגדיר מחרוזת תבנית עם placeholders ולספק Status.Part
אובייקטים כדי למלא את ה-placeholders האלה. ה-Status.Part
יכול להיות דינמי, כמו שעון עצר או טיימר .
בדוגמה הבאה אפשר לראות איך ליצור סטטוס שמציג את הטקסט 'הפעלה למשך [שעון עצר]':
// Define a template with placeholders for the activity type and the timer. val statusTemplate = "#type# for #time#" // Set the start time for a stopwatch. // Use SystemClock.elapsedRealtime() for time-based parts. val runStartTime = SystemClock.elapsedRealtime() val ongoingActivityStatus = Status.Builder() // Sets the template string. .addTemplate(statusTemplate) // Fills the #type# placeholder with a static text part. .addPart("type", Status.TextPart("Run")) // Fills the #time# placeholder with a stopwatch part. .addPart("time", Status.StopwatchPart(runStartTime)) .build()
לבסוף, כדי לקשר את Status
אל OngoingActivity
, צריך להתקשר אל setStatus()
ב-OngoingActivity.Builder
.
val ongoingActivity = OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder) // ... // Add the status to the OngoingActivity. .setStatus(ongoingActivityStatus) .build()
התאמות אישיות נוספות
בנוסף לStatus
, יש כמה דרכים להתאים אישית את הפעילות או ההתראות השוטפות. עם זאת, יכול להיות שההתאמות האישיות האלה לא ישמשו אתכם, בהתאם להטמעה של יצרן הציוד המקורי.
התראה פעילה
- הגדרת הקטגוריה קובעת את העדיפות של הפעילות המתמשכת.
CATEGORY_CALL
: שיחת וידאו או שיחה קולית נכנסת או בקשה דומה לתקשורת סינכרונית-
CATEGORY_NAVIGATION
: מפה או מסלול מפורט -
CATEGORY_TRANSPORT
: שליטה בהעברת מדיה להפעלה CATEGORY_ALARM
: שעון מעורר או טיימר-
CATEGORY_WORKOUT
: אימון CATEGORY_LOCATION_SHARING
: שיתוף מיקום זמני קטגוריה)CATEGORY_STOPWATCH
: שעון עצר
פעילות שוטפת
סמל מונפש: וקטור בשחור-לבן, רצוי עם רקע שקוף. מוצג בתצוגת השעון במצב פעיל. אם לא מספקים סמל אנימציה, המערכת משתמשת בסמל ברירת המחדל של ההתראה. סמל ברירת המחדל של ההתראה שונה בכל אפליקציה.
סמל סטטי: סמל וקטורי עם רקע שקוף. מוצג בתצוגת השעון במצב אווירה. אם לא מוגדר סמל עם אנימציה, הסמל הסטטי משמש בתצוגת השעון במצב פעיל. אם לא מציינים סמל, המערכת משתמשת בסמל של ההתראה. אם אף אחד מהם לא מוגדר, נוצרת חריגה. (סמל האפליקציה עדיין מופיע במרכז האפליקציות).
OngoingActivityStatus: טקסט פשוט או
Chronometer
. מוצג בקטע האחרונים במרכז האפליקציות. אם לא מספקים ערך, המערכת משתמשת ב"טקסט ההקשר" של ההתראה.Touch Intent:
PendingIntent
שמשמש למעבר חזרה לאפליקציה אם המשתמש מקיש על סמל הפעילות המתמשכת. מוצג בתצוגת השעון או בפריט של מרכז האפליקציות. יכול להיות שהיא שונה מהכוונה המקורית ששימשה להפעלת האפליקציה. אם לא מציינים כוונה, נעשה שימוש בכוונה של תוכן ההתראה. אם אף אחת מהן לא מוגדרת, נוצרת חריגה.
LocusId
: מזהה שמקצה את קיצור הדרך במרכז האפליקציות שאליו משויכת הפעילות המתמשכת. האינדיקטור מוצג במרכז האפליקציות בקטע מהזמן האחרון בזמן שהפעילות מתבצעת. אם לא מספקים את המזהה, מרכז האפליקציות מסתיר את כל פריטי האפליקציה בקטע הפעולות האחרונות מאותו חבילה ומציג רק את הפעילות המתמשכת.Ongoing Activity ID: מזהה שמשמש להבחנה בין קריאות ל-
fromExistingOngoingActivity()
כשיש לאפליקציה יותר מפעילות אחת מתמשכת.
עדכון פעילות מתמשכת
ברוב המקרים, מפתחים יוצרים התראה חדשה ופעילות חדשה שמתבצעת ברקע כשהם צריכים לעדכן את הנתונים במסך. עם זאת, ממשק ה-API של פעילות מתמשכת מציע גם שיטות עזר לעדכון של OngoingActivity
אם רוצים לשמור על מופע ולא ליצור אותו מחדש.
אם האפליקציה פועלת ברקע, היא יכולה לשלוח עדכונים לממשק ה-API של הפעילות המתמשכת. עם זאת, לא מומלץ לעשות זאת בתדירות גבוהה מדי, כי שיטת העדכון מתעלמת מקריאות שקרובות מדי זו לזו. כמה עדכונים בדקה זה סביר.
כדי לעדכן את הפעילות המתמשכת ואת ההתראה שפורסמה, משתמשים באובייקט שיצרתם קודם ומפעילים את update()
, כמו בדוגמה הבאה:
ongoingActivity.update(context, newStatus)
לנוחותכם, יש שיטה סטטית ליצירת פעילות מתמשכת.
OngoingActivity.recoverOngoingActivity(context)
.update(context, newStatus)
איך מפסיקים פעילות מתמשכת
כשהאפליקציה מסיימת לפעול כפעילות מתמשכת, היא צריכה רק לבטל את ההתראה המתמשכת.
אפשר גם לבטל את ההתראה או את הפעילות המתמשכת כשהן עוברות לחזית, ואז ליצור אותן מחדש כשחוזרים לרקע, אבל זה לא חובה.
השהיית פעילות מתמשכת
אם באפליקציה יש פעולת עצירה מפורשת, צריך להמשיך את הפעילות המתמשכת אחרי שהיא מופעלת מחדש. אם לאפליקציה אין פעולת עצירה מפורשת, הפעילות מסתיימת כשהיא מושהית.
שיטות מומלצות
כשעובדים עם Ongoing Activity API, חשוב לזכור את הדברים הבאים:
מגדירים סמל סטטי לפעילות המתמשכת, באופן מפורש או כגיבוי באמצעות ההתראה. אם לא, תקבלו
IllegalArgumentException
.שימוש בסמלי וקטור בשחור-לבן עם רקע שקוף.
הגדרת כוונת מגע לפעילות שמתבצעת, באופן מפורש או כגיבוי באמצעות ההתראה. אם לא, תקבלו
IllegalArgumentException
.אם באפליקציה יש יותר מפעילות אחת
MAIN LAUNCHER
שמוצהרת במניפסט, צריך לפרסם קיצור דרך דינמי ולשייך אותו לפעילות המתמשכת באמצעותLocusId
.
פרסום התראות על מדיה כשמפעילים מדיה במכשירי Wear OS
אם תוכן מדיה מושמע במכשיר Wear OS, מפרסמים התראה על מדיה. כך המערכת יכולה ליצור את הפעילות המתאימה שמתבצעת באופן שוטף.
אם אתם משתמשים ב-Media3, ההתראה מתפרסמת באופן אוטומטי. אם יוצרים את ההתראה באופן ידני, צריך להשתמש ב-MediaStyleNotificationHelper.MediaStyle
, וב-MediaSession
המתאים צריך להיות מאוכלס הערך session activity.
מומלץ בשבילך
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- יצירת התראה {:#notification}
- יצירת אינטראקציה עם משתמשי Wear OS בדרכים חדשות באמצעות Ongoing Activity API
- יצירת הודעה שניתן להרחיב {:#expandable-notification}