בניית מארח ווידג'טים

מסך הבית של Android, שזמין ברוב המכשירים עם Android, מאפשר למשתמשים להטמיע ווידג'טים של אפליקציות (או ווידג'טים) כדי לקבל גישה מהירה לתוכן. אם אתם מפתחים אפליקציה שתחלף את מסך הבית או אפליקציה דומה, תוכלו גם לאפשר למשתמשים להטמיע ווידג'טים על ידי הטמעת AppWidgetHost. רוב האפליקציות לא צריכות לעשות זאת, אבל אם אתם יוצרים מארח משלכם, חשוב להבין את ההתחייבויות החוזיות שהמארח מסכים להן באופן משתמע.

בדף הזה נסביר על האחריות הכרוכה בהטמעת AppWidgetHost בהתאמה אישית. לדוגמה ספציפית להטמעת AppWidgetHost, אפשר לעיין בקוד המקור של מסך הבית של Android‏ LauncherAppWidgetHost.

הנה סקירה כללית של הכיתות והמושגים המרכזיים שקשורים להטמעת AppWidgetHost בהתאמה אישית:

  • מארח של ווידג'ט של אפליקציה: ה-AppWidgetHost מספק את האינטראקציה עם שירות AppWidget לאפליקציות שמטמיעות ווידג'טים בממשק המשתמש שלהן. ל-AppWidgetHost חייב להיות מזהה ייחודי בחבילה של המארח. המזהה הזה נשמר בכל השימושים במארח. המזהה הוא בדרך כלל ערך מקודד מראש שמקצים באפליקציה.

  • מזהה הווידג'ט של האפליקציה: לכל מופע של ווידג'ט מוקצה מזהה ייחודי בזמן הקישור. אפשר לעיין ב-bindAppWidgetIdIfAllowed(), ולקבל מידע נוסף בקטע קישור ווידג'טים שבהמשך. המארח מקבל את המזהה הייחודי באמצעות allocateAppWidgetId(). המזהה הזה נשאר בתוקף לכל משך החיים של הווידג'ט, עד שהוא נמחק מהמארח. כל מצב ספציפי למארח – כמו הגודל והמיקום של הווידג'ט – חייב להיות שמור בחבילת האירוח ולשויך למזהה הווידג'ט של האפליקציה.

  • תצוגת המארח של הווידג'ט של האפליקציה: אפשר לחשוב על AppWidgetHostView כמסגרת שבה הווידג'ט עטוף בכל פעם שהוא צריך להופיע. הווידג'ט משויך ל-AppWidgetHostView בכל פעם שהמארח מנפח אותו.

    • כברירת מחדל, המערכת יוצרת AppWidgetHostView, אבל המארח יכול ליצור תת-סוג משלו של AppWidgetHostView על ידי הרחבה שלו.
    • החל מ-Android 12 (רמת API 31), ב-AppWidgetHostView מופיעים השיטות setColorResources() ו-resetColorResources() לטיפול בצבע שעבר עומס דינמי. המארח אחראי לספק את הצבעים לשיטות האלה.
  • חבילת אפשרויות: ה-AppWidgetHost משתמש בחבילת האפשרויות כדי להעביר מידע ל-AppWidgetProvider לגבי אופן הצגת הווידג'ט – לדוגמה, רשימת טווחי הגדלים – ואם הווידג'ט מוצג במסך הנעילה או במסך הבית. המידע הזה מאפשר ל-AppWidgetProvider להתאים אישית את התוכן והמראה של הווידג'ט בהתאם לאופן שבו הוא מוצג ולמיקום שבו הוא מוצג. אפשר להשתמש ב-updateAppWidgetOptions() וב-updateAppWidgetSize() כדי לשנות את החבילה של הווידג'ט. שתי השיטות האלה מפעילות את הקריאה החוזרת (callback) onAppWidgetOptionsChanged() ל-AppWidgetProvider.

קישור ווידג'טים

כשמשתמש מוסיף ווידג'ט למארח, מתרחש תהליך שנקרא קישור. קישור מתייחס לשיוך של מזהה ווידג'ט מסוים של אפליקציה למארח ספציפי ול-AppWidgetProvider ספציפי.

ממשקי API לקישורים מאפשרים גם למארח לספק ממשק משתמש מותאם אישית לקישור. כדי להשתמש בתהליך הזה, האפליקציה צריכה להצהיר על ההרשאה BIND_APPWIDGET במניפסט של המארח:

<uses-permission android:name="android.permission.BIND_APPWIDGET" />

אבל זה רק השלב הראשון. בזמן הריצה, המשתמש צריך להעניק לאפליקציה הרשאה מפורשת להוסיף ווידג'ט למארח. כדי לבדוק אם לאפליקציה יש הרשאה להוסיף את הווידג'ט, משתמשים בשיטה bindAppWidgetIdIfAllowed(). אם הפונקציה bindAppWidgetIdIfAllowed() מחזירה את הערך false, האפליקציה צריכה להציג תיבת דו-שיח שבה המשתמש יתבקש להעניק הרשאה: 'אישור' להוספת הווידג'ט הנוכחי, או 'אישור תמיד' כדי לכסות את כל ההוספות העתידיות של ווידג'טים.

קטע הקוד הזה מציג דוגמה להצגת תיבת הדו-שיח:

Kotlin

val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply {
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName)
    // This is the options bundle described in the preceding section.
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options)
}
startActivityForResult(intent, REQUEST_BIND_APPWIDGET)

Java

Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);
// This is the options bundle described in the preceding section.
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
startActivityForResult(intent, REQUEST_BIND_APPWIDGET);

המארח צריך לבדוק אם הווידג'ט שהמשתמש הוסיף צריך הגדרה. למידע נוסף, ראו איך מאפשרים למשתמשים להגדיר ווידג'טים של אפליקציות.

תחומי האחריות של המארחים

אפשר לציין כמה הגדרות אישיות של ווידג'טים באמצעות המטא-נתונים של AppWidgetProviderInfo. אפשר לאחזר את אפשרויות התצורה האלה, שמפורטות בהרחבה בקטעים הבאים, מהאובייקט AppWidgetProviderInfo שמשויך לספק הווידג'ט.

ללא קשר לגרסה של Android שאליה אתם מטרגטים, כל המארחים צריכים לבצע את הפעולות הבאות:

  • כשמוסיפים ווידג'ט, מקצים לו מזהה ווידג'ט כפי שמתואר למעלה. כשמסירים ווידג'ט מהמארח, צריך לבצע קריאה ל-deleteAppWidgetId() כדי לבטל את ההקצאה של מזהה הווידג'ט.

  • כשמוסיפים ווידג'ט, צריך לבדוק אם צריך להפעיל את פעילות ההגדרה. בדרך כלל, המארח צריך להפעיל את פעילות ההגדרה של הווידג'ט אם היא קיימת ולא מסומנת כאופציונלית, על ידי ציון הדגלים configuration_optional ו-reconfigurable. לפרטים נוספים, אפשר לעיין במאמר עדכון הווידג'ט מהפעילות של הגדרת הווידג'ט. זהו שלב הכרחי עבור ווידג'טים רבים כדי שיוכלו להופיע.

  • בווידג'טים מצוינים רוחב וגובה ברירת מחדל במטא-נתונים של AppWidgetProviderInfo. הערכים האלה מוגדרים בתאים – החל מ-Android 12, אם צוינו targetCellWidth ו-targetCellHeight – או ב-dps אם צוינו רק minWidth ו-minHeight. מאפייני התאמת הגודל של ווידג'טים

    חשוב לוודא שהווידג'ט מוצג עם לפחות 100 דפים לדקה. לדוגמה, הרבה מארחים מסדרים סמלים ווידג'טים בתצוגת רשת. בתרחיש הזה, המארח מוסיף את הווידג'ט כברירת מחדל באמצעות מספר התאים המינימלי שעומד באילוצים minWidth ו-minHeight.

בנוסף לדרישות שמפורטות בקטע הקודם, בגרסאות מסוימות של הפלטפורמה יש תכונות שמחייבות את המארח לנקוט בצעדים חדשים.

איך קובעים את הגישה בהתאם לגרסה של Android שמוגדרת לטירגוט

Android 12

ב-Android 12 (רמת API 31) יש List<SizeF> נוסף בחבילה שמכיל את רשימת הגדלים האפשריים ב-dps שיכולים להיות למכונה של הווידג'ט בחבילת האפשרויות. מספר הגדלים שאפשר לספק תלוי בהטמעה של המארח. בדרך כלל, המארחים מספקים שני גדלים לטלפונים – לרוחב ולגובה – וארבעה גדלים למכשירים מתקפלים.

יש מגבלה של MAX_INIT_VIEW_COUNT (16) על מספר הערכים השונים של RemoteViews ש-AppWidgetProvider יכול לספק ל-RemoteViews. מאחר שאובייקטים מסוג AppWidgetProvider ממפים אובייקט RemoteViews לכל מידה ב-List<SizeF>, אין לספק יותר מ-MAX_INIT_VIEW_COUNT מידות.

ב-Android 12 נוספו גם המאפיינים maxResizeWidth ו-maxResizeHeight ב-DPS. מומלץ שווידג'ט שמשתמש לפחות באחד מהמאפיינים האלה לא יחרוג מהגודל שצוין במאפיינים.

מקורות מידע נוספים

  • מידע נוסף זמין במסמכי העזרה של Glance.