ההגדרות המהירות הן כפתורים שמוצגים בחלונית ההגדרות המהירות, ומייצגים פעולות שהמשתמשים יכולים להקיש עליהם כדי לבצע במהירות משימות חוזרות.
האפליקציה יכולה לספק למשתמשים משבצת מותאמת אישית באמצעות המחלקה TileService, ולהשתמש באובייקט Tile כדי לעקוב אחרי מצב המשבצת. לדוגמה, אפשר ליצור משבצת שמאפשרת למשתמשים להפעיל או להשבית VPN שמוצע על ידי האפליקציה.
מתי כדאי ליצור משבצת
מומלץ ליצור משבצות לפונקציות ספציפיות שאתם מצפים שהמשתמשים יגשו אליהן לעיתים קרובות או יצטרכו גישה מהירה אליהן (או שניהם). האריחים הכי יעילים הם אלה שעומדים בשני הקריטריונים האלה, ומספקים גישה מהירה לפעולות שמבצעים לעיתים קרובות.
לדוגמה, אפשר ליצור משבצת לאפליקציית כושר שתאפשר למשתמשים להתחיל במהירות אימון. עם זאת, לא מומלץ ליצור כרטיס לאותה אפליקציה שיאפשר למשתמשים לעיין בכל היסטוריית האימונים שלהם.
כדי לשפר את יכולת הגילוי של המשבצת ואת קלות השימוש בה, מומלץ להימנע משיטות מסוימות:
לא מומלץ להשתמש במשבצות כדי להפעיל אפליקציה. במקום זאת, כדאי להשתמש בקיצור דרך לאפליקציה או במפעיל אפליקציות רגיל.
אל תשתמשו במשבצות לפעולות חד-פעמיות של משתמשים. במקום זאת, אפשר להשתמש בקיצור דרך לאפליקציה או בהתראה.
לא מומלץ ליצור יותר מדי משבצות. מומלץ להשתמש במקסימום שני קיצורי דרך לכל אפליקציה. אפשר להשתמש בקיצור דרך לאפליקציה במקום זאת.
אל תשתמשו במשבצות שמציגות מידע אבל לא מאפשרות למשתמשים לבצע פעולות. במקום זאת, אפשר להשתמש בהתראה או בווידג'ט.
יצירת משבצת
כדי ליצור משבצת, צריך קודם ליצור סמל מתאים למשבצת, ואז ליצור ולהצהיר על TileService בקובץ המניפסט של האפליקציה.
בדוגמה של ההגדרות המהירות מוסבר איך ליצור ולנהל לחצן.
יצירת סמל בהתאמה אישית
צריך לספק סמל מותאם אישית שיוצג במשבצת בחלונית ההגדרות המהירות. (תוסיפו את הסמל הזה כשמצהירים על TileService, כפי שמתואר בקטע הבא). הסמל צריך להיות לבן מלא עם רקע שקוף, בגודל 24 x 24dp ובפורמט VectorDrawable.
יוצרים סמל שמרמז באופן ויזואלי על המטרה של האריח. כך המשתמשים יכולים לזהות בקלות אם המשבצת מתאימה לצרכים שלהם. לדוגמה, אפשר ליצור סמל של שעון עצר לריבוע של אפליקציית כושר שמאפשרת למשתמשים להתחיל אימון.
יצירה והצהרה של TileService
יוצרים שירות לרכיב ה-Tile שמרחיב את המחלקה TileService.
Kotlin
class MyQSTileService: TileService() { // Called when the user adds your tile. override fun onTileAdded() { super.onTileAdded() } // Called when your app can update your tile. override fun onStartListening() { super.onStartListening() } // Called when your app can no longer update your tile. override fun onStopListening() { super.onStopListening() } // Called when the user taps on your tile in an active or inactive state. override fun onClick() { super.onClick() } // Called when the user removes your tile. override fun onTileRemoved() { super.onTileRemoved() } }
Java
public class MyQSTileService extends TileService { // Called when the user adds your tile. @Override public void onTileAdded() { super.onTileAdded(); } // Called when your app can update your tile. @Override public void onStartListening() { super.onStartListening(); } // Called when your app can no longer update your tile. @Override public void onStopListening() { super.onStopListening(); } // Called when the user taps on your tile in an active or inactive state. @Override public void onClick() { super.onClick(); } // Called when the user removes your tile. @Override public void onTileRemoved() { super.onTileRemoved(); } }
מצהירים על TileService בקובץ המניפסט של האפליקציה. מוסיפים את השם והתווית של TileService, את הסמל המותאם אישית שיצרתם בקטע הקודם ואת ההרשאה המתאימה.
<service
android:name=".MyQSTileService"
android:exported="true"
android:label="@string/my_default_tile_label" // 18-character limit.
android:icon="@drawable/my_default_icon_label"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
ניהול TileService
אחרי שיוצרים את TileService ומצהירים עליו בקובץ מניפסט של אפליקציה, צריך לנהל את המצב שלו.
TileService הוא שירות מאוגד. ה-TileService שלכם נקשר כשמתקבלת בקשה מהאפליקציה או אם המערכת צריכה לתקשר איתו. מחזור החיים של שירות מאוגד כולל בדרך כלל את ארבע שיטות הקריאה החוזרת הבאות: onCreate(), onBind(), onUnbind() ו-onDestroy(). המערכת מפעילה את השיטות האלה בכל פעם שהשירות עובר לשלב חדש במחזור החיים.
סקירה כללית על מחזור החיים של TileService
בנוסף לקריאות החוזרות (callbacks) ששולטות במחזור החיים של השירות המקשר, צריך להטמיע שיטות אחרות שספציפיות למחזור החיים של TileService. יכול להיות שה-methods האלה יופעלו מחוץ ל-onCreate() ול-onDestroy(), כי ה-methods של מחזור החיים של Service וה-methods של מחזור החיים של TileService מופעלים בשני שרשורים אסינכרוניים נפרדים.
מחזור החיים TileService מכיל את השיטות הבאות, שהמערכת מפעילה בכל פעם שהרכיב TileService עובר לשלב חדש במחזור החיים:
onTileAdded(): השיטה הזו מופעלת רק כשהמשתמש מוסיף את המשבצת שלכם בפעם הראשונה, וגם אם המשתמש מסיר את המשבצת ומוסיף אותה שוב. זה הזמן הכי טוב לבצע אתחול חד-פעמי. עם זאת, יכול להיות שהפעולה הזו לא תספיק כדי לבצע את כל האתחול הנדרש.
onStartListening()ו-onStopListening(): הפונקציות האלה מופעלות בכל פעם שהאפליקציה מעדכנת את האריח, והן מופעלות לעיתים קרובות. האפליקציהTileServiceנשארת מקושרת ביןonStartListening()לביןonStopListening(), ומאפשרת לאפליקציה לשנות את הלחצן ולשלוח עדכונים.
onTileRemoved(): השיטה הזו מופעלת רק אם המשתמש מסיר את המשבצת שלכם.
בחירת מצב האזנה
האפליקציה TileService פועלת במצב פעיל או במצב לא פעיל. מומלץ להשתמש במצב פעיל, שצריך להצהיר עליו בקובץ המניפסט של האפליקציה. אחרת, TileService הוא המצב הרגיל ואין צורך להצהיר עליו.
אל תניחו שTileService יתקיים מחוץ לזוג השיטות onStartListening() ו-onStopListening().
מצב פעיל (מומלץ)
משתמשים במצב פעיל עבור TileService שמקשיב למצב שלו ועוקב אחריו בתהליך משלו. TileService במצב פעיל מחויב ב-onTileAdded(),
onTileRemoved(), באירועי הקשה ובבקשות של תהליך האפליקציה.
מומלץ להשתמש במצב פעיל אם TileService מקבל הודעה כשהמצב של המשבצת צריך להתעדכן על ידי התהליך שלו. האריחים הפעילים מגבילים את העומס על המערכת כי הם לא צריכים להיות קשורים בכל פעם שהחלונית 'הגדרות מהירות' הופכת גלויה למשתמש.
אפשר להפעיל את ה-method הסטטית TileService.requestListeningState() כדי לבקש להתחיל את מצב ההאזנה ולקבל קריאה חוזרת אל onStartListening().
כדי להצהיר על מצב פעיל, מוסיפים את META_DATA_ACTIVE_TILE לקובץ המניפסט של האפליקציה.
<service ...>
<meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
android:value="true" />
...
</service>
מצב לא פעיל
מצב לא פעיל הוא המצב הרגיל. TileService נמצא במצב לא פעיל אם הוא מאוגד בכל פעם שהמשתמש רואה את הרכיב. המשמעות היא שיכול להיות ש-TileService ייצור ויקשר את עצמו מחדש בזמנים שמעבר לשליטתו. יכול להיות שהשירות לא יקשר לאפליקציה ויוסר כשהמשתמש לא יצפה במשבצת.
האפליקציה מקבלת קריאה חוזרת אל onStartListening() אחרי שהמשתמש פותח את חלונית ההגדרות המהירות. אפשר לעדכן את אובייקט Tile כמה פעמים שרוצים בין התאריכים onStartListening() ל-onStopListening().
אין צורך להצהיר על מצב לא פעיל – פשוט לא מוסיפים את התג META_DATA_ACTIVE_TILE לקובץ המניפסט של האפליקציה.
סקירה כללית של מצבי הכרטיסים
אחרי שמשתמש מוסיף את המשבצת שלכם, היא תמיד תהיה באחד מהמצבים הבאים.
STATE_ACTIVE: מציין מצב פעיל או מופעל. במצב הזה, המשתמש יכול לקיים אינטראקציה עם המשבצת שלכם.לדוגמה, במשבצת של אפליקציית כושר שמאפשרת למשתמשים להתחיל אימון עם טיימר,
STATE_ACTIVEמציין שהמשתמש התחיל אימון והטיימר פועל.
STATE_INACTIVE: מציין מצב מושבת או מושהה. במצב הזה, המשתמש יכול לקיים אינטראקציה עם המשבצת שלכם.אם נחזור לדוגמה של משבצת האפליקציה לכושר, משבצת ב-
STATE_INACTIVEתציין שהמשתמש לא התחיל סשן אימון, אבל הוא יכול לעשות זאת אם הוא רוצה.
STATE_UNAVAILABLE: מציין מצב של זמינות זמנית. המשתמש לא יכול לבצע פעולות במשבצת שלכם כשהיא במצב הזה.לדוגמה, אם מופיעה משבצת עם
STATE_UNAVAILABLE, המשמעות היא שהמשתמש לא יכול להשתמש במשבצת הזו כרגע מסיבה כלשהי.
המערכת מגדירה רק את המצב הראשוני של אובייקט Tile. אתם מגדירים את המצב של האובייקט Tile לאורך שאר מחזור החיים שלו.
יכול להיות שהמערכת תצבע את סמל המשבצת ואת הרקע כדי לשקף את הסטטוס של אובייקט Tile. אובייקטים עם ההגדרה Tile הם הכהים ביותר, ואובייקטים עם ההגדרות STATE_ACTIVESTATE_INACTIVE ו-STATE_UNAVAILABLE הם בהירים יותר. הגוון המדויק תלוי ביצרן ובגרסה.
עדכון המשבצת
אחרי שתקבלו שיחת טלפון חוזרת למספר onStartListening(), תוכלו לעדכן את המשבצת.
בהתאם למצב של ה-tile, הוא יכול להתעדכן לפחות פעם אחת עד לקבלת קריאה חוזרת אל onStopListening().
במצב פעיל, אפשר לעדכן את ה-tile בדיוק פעם אחת לפני שמקבלים קריאה חוזרת אל onStopListening(). במצב לא פעיל, אפשר לעדכן את המשבצת כמה פעמים שרוצים בין השעות onStartListening() ל-onStopListening().
אפשר לאחזר את אובייקט Tile באמצעות קריאה ל-getQsTile(). כדי לעדכן שדות ספציפיים באובייקט Tile, קוראים לשיטות הבאות:
אחרי שמגדירים את השדות של אובייקט Tile לערכים הנכונים, צריך להתקשר אל updateTile() כדי לעדכן את האריח. המערכת תנתח את נתוני האריח המעודכנים ותעדכן את ממשק המשתמש.
Kotlin
data class StateModel(val enabled: Boolean, val label: String, val icon: Icon) override fun onStartListening() { super.onStartListening() val state = getStateFromService() qsTile.label = state.label qsTile.contentDescription = tile.label qsTile.state = if (state.enabled) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE qsTile.icon = state.icon qsTile.updateTile() }
Java
public class StateModel { final boolean enabled; final String label; final Icon icon; public StateModel(boolean e, String l, Icon i) { enabled = e; label = l; icon = i; } } @Override public void onStartListening() { super.onStartListening(); StateModel state = getStateFromService(); Tile tile = getQsTile(); tile.setLabel(state.label); tile.setContentDescription(state.label); tile.setState(state.enabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE); tile.setIcon(state.icon); tile.updateTile(); }
טיפול בהקשות
אם הריבוע שלכם נמצא בSTATE_ACTIVE או בSTATE_INACTIVE, המשתמשים יכולים להקיש עליו כדי להפעיל פעולה. לאחר מכן המערכת מפעילה את הקריאה החוזרת (callback) onClick() של האפליקציה.
אחרי שהאפליקציה מקבלת קריאה חוזרת אל onClick(), היא יכולה להפעיל תיבת דו-שיח או פעילות, להפעיל עבודה ברקע או לשנות את המצב של הלחצן.
Kotlin
var clicks = 0 override fun onClick() { super.onClick() counter++ qsTile.state = if (counter % 2 == 0) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE qsTile.label = "Clicked $counter times" qsTile.contentDescription = qsTile.label qsTile.updateTile() }
Java
int clicks = 0; @Override public void onClick() { super.onClick(); counter++; Tile tile = getQsTile(); tile.setState((counter % 2 == 0) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE); tile.setLabel("Clicked " + counter + " times"); tile.setContentDescription(tile.getLabel()); tile.updateTile(); }
הפעלת תיבת דו-שיח
showDialog() מכווץ את החלונית 'הגדרות מהירות' ומציג תיבת דו-שיח.
אם הפעולה דורשת קלט נוסף או הסכמת משתמש, כדאי להשתמש בתיבת דו-שיח כדי להוסיף הקשר.
הפעלת פעילות
startActivityAndCollapse() מתחיל פעילות תוך כדי כיווץ החלונית. פעילויות שימושיות אם יש מידע מפורט יותר להצגה מאשר בתיבת דו-שיח, או אם הפעולה שלכם היא אינטראקטיבית מאוד.
אם האפליקציה שלכם דורשת אינטראקציה משמעותית של המשתמש, כדאי להפעיל פעילות באפליקציה רק כמוצא אחרון. במקום זאת, כדאי להשתמש בתיבת דו-שיח או במתג.
הקשה ארוכה על משבצת פותחת את המסך פרטי האפליקציה למשתמש. כדי לשנות את ההתנהגות הזו ולהפעיל פעילות להגדרת העדפות, מוסיפים <intent-filter> לאחת מהפעילויות עם ACTION_QS_TILE_PREFERENCES.
החל מ-Android API 28, ל-PendingIntent חייב להיות Intent.FLAG_ACTIVITY_NEW_TASK:
if (Build.VERSION.SDK_INT >= 28) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
אפשר גם להוסיף את הדגל AndroidManifest.xml בקטע Activity הספציפי.
סימון המשבצת כניתנת להפעלה ולהשבתה
מומלץ לסמן את המשבצת כניתנת להחלפה אם היא פועלת בעיקר כמתג דו-מצבי (שזה אופן הפעולה הנפוץ ביותר של משבצות). המידע הזה עוזר לספק למערכת ההפעלה מידע על ההתנהגות של האריח ולשפר את הנגישות הכוללת.
מגדירים את המטא-נתונים TOGGLEABLE_TILE לערך true כדי לסמן את המשבצת כניתנת להחלפה.
<service ...>
<meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
android:value="true" />
</service>
ביצוע רק פעולות בטוחות במכשירים נעולים בצורה מאובטחת
יכול להיות שהאריח יוצג בחלק העליון של מסך הנעילה במכשירים נעולים. אם המשבצת מכילה מידע רגיש, צריך לבדוק את הערך של isSecure() כדי לקבוע אם המכשיר נמצא במצב מאובטח, וTileService צריך לשנות את ההתנהגות שלו בהתאם.
אם הפעולה של הלחצן ב-Quick Settings בטוחה לביצוע כשהמכשיר נעול, אפשר להשתמש ב-startActivity()
כדי להפעיל פעילות מעל מסך הנעילה.
אם הפעולה של האריח לא בטוחה, משתמשים ב-unlockAndRun() כדי לבקש מהמשתמש לבטל את הנעילה של המכשיר. אם הפעולה בוצעה ללא שגיאות, המערכת מבצעת את אובייקט Runnable שמועבר לשיטה הזו.
סיווג המשבצת
כדי לשפר את חוויית המשתמש בהגדרות המהירות, אתם יכולים לסווג את הכפתור. המשבצות מסודרות בקטגוריות כמו קישוריות, תצוגה ופרטיות. המערכת משתמשת בקטגוריות האלה כדי למיין ולקבץ את הלחצנים במצב העריכה של ההגדרות המהירות, וכך המשתמשים יכולים למצוא ולנהל אותם בקלות.
הטמעה
כדי לציין קטגוריה ל-TileService, מוסיפים שדה מטא-נתונים להצהרת השירות בקובץ AndroidManifest.xml:
- ב-
AndroidManifest.xml, בתוך רכיב<service>שלTileService, מוסיפים רכיב<meta-data>. android:name: צריך להגדיר את הערך הזה ל-android.service.quicksettings.TILE_CATEGORY.-
android:value: מקצים אחת מקבועי הקטגוריות שהוגדרו מראש, כמוandroid.service.quicksettings.CATEGORY_CONNECTIVITYאוandroid.service.quicksettings.CATEGORY_DISPLAY.
כמו בדוגמה הבאה:
<service
android:name=".MyConnectivityTileService"
[...]
>
<meta-data android:name="android.service.quicksettings.TILE_CATEGORY"
android:value="android.service.quicksettings.CATEGORY_CONNECTIVITY" />
</service>
ה-API מספק קבוצה של קטגוריות מוגדרות מראש שאפשר לבחור מתוכן. הקטגוריות האלה מוגדרות כקבועי מחרוזת במחלקה TileService.
אם לא מציינים קטגוריה, המערכת מקצה באופן אוטומטי קטגוריית ברירת מחדל:
- מאפליקציות מערכת: לגבי משבצות שהן חלק מאפליקציית מערכת.
- מאפליקציות שהתקנתם: לריבועים מאפליקציות שהמשתמשים התקינו.
למרות שמכשירי Google Pixel משתמשים בקטגוריות בהגדרות המהירות, יצרני ציוד מקורי יכולים להשתמש במידע הזה או להתעלם ממנו בממשקי המשתמש של המערכת שלהם.
בקשה מהמשתמש להוסיף את המשבצת
כדי להוסיף את המשבצת באופן ידני, המשתמשים צריכים לבצע כמה שלבים:
- מחליקים למטה כדי לפתוח את חלונית ההגדרות המהירות.
- מקישים על לחצן העריכה.
- גוללים בין כל כרטיסי המידע במכשיר עד שמאתרים את כרטיס המידע שלכם.
- לוחצים לחיצה ארוכה על הכפתור וגוררים אותו לרשימת הכפתורים הפעילים.
המשתמש יכול גם להזיז או להסיר את המשבצת שלכם בכל שלב.
החל מ-Android 13, אפשר להשתמש בשיטה requestAddTileService() כדי להקל על המשתמשים להוסיף את הריבוע שלכם למכשיר. בשיטה הזו, המשתמשים מקבלים בקשה להוסיף את הכפתור שלכם ישירות לחלונית ההגדרות המהירות. ההנחיה כוללת את שם האפליקציה, התווית שסופקה והסמל.
public void requestAddTileService (
ComponentName tileServiceComponentName,
CharSequence tileLabel,
Icon icon,
Executor resultExecutor,
Consumer<Integer> resultCallback
)
הקריאה החוזרת מכילה מידע על כך שהמשבצת נוספה או לא נוספה, אם היא כבר הייתה שם או אם התרחשה שגיאה כלשהי.
צריך להפעיל שיקול דעת כשמחליטים מתי להציג למשתמשים בקשות ומתי להציג אותן. מומלץ לקרוא ל-requestAddTileService() רק בהקשר – למשל, כשהמשתמש מקיים אינטראקציה ראשונה עם תכונה שהרכיב מספק.
המערכת יכולה להפסיק לעבד בקשות עבור ComponentName מסוים אם המשתמש דחה אותו מספיק פעמים בעבר. המשתמש נקבע לפי Context שמשמש לאחזור השירות הזה – הוא חייב להיות זהה למשתמש הנוכחי.