מצב תנומה של אפליקציה

אם האפליקציה שלכם מיועדת ל-Android 11 (רמת API 30) ומעלה, והמשתמש לא מקיים אינטראקציה עם האפליקציה במשך כמה חודשים, המערכת מעבירה את האפליקציה למצב שינה. המערכת עוברת אופטימיזציה לנפח אחסון במקום לביצועים, והיא מגנה על נתוני המשתמשים. התנהגות המערכת הזו דומה למה שקורה כשהמשתמש עוצר את האפליקציה באופן ידני דרך הגדרות המערכת.

ההשפעות של מצב תנומה

כפי שמוצג בטבלה 1, ההשפעות של מצב שינה תלויות בגרסת ה-SDK לטירגוט של האפליקציה, וגם במכשיר שבו האפליקציה פועלת:

טבלה 1. ההשפעות של מצב התנומה על האפליקציה
גרסת היעד של SDK מאפייני המכשיר ההשפעות של מצב תנומה
‫Android מגרסה 12 ואילך מערכת Android מגרסה 12 ואילך

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

האפליקציה לא יכולה להריץ משימות או התראות ברקע.

האפליקציה לא יכולה לקבל התראות פוש, כולל הודעות עם עדיפות גבוהה שנשלחות דרך העברת הודעות בענן ב-Firebase.

כל הקבצים במטמון של האפליקציה יוסרו.

‫Android 11 פועל ב-Android 11 ההרשאות של האפליקציה בזמן ריצה מאופסות.
‫Android 11 מערכת Android בגרסה 6.0 (רמת API‏ 23) עד גרסה 10 (רמת API‏ 29), כולל, ומופעלת על ידי Google Play Services

ההרשאות של האפליקציה בזמן ריצה מאופסות.

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

התנהגות המערכת כשאפליקציה יוצאת ממצב שינה

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

עם זאת, המערכת לא מבצעת את הפעולות הבאות עבור האפליקציה:

  1. צריך להעניק מחדש את ההרשאות של האפליקציה בזמן ריצה.

    המשתמש צריך להעניק מחדש את ההרשאות האלה לאפליקציה שלכם.

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

    כדי לתמוך בתהליך העבודה הזה בקלות רבה יותר, אפשר להשתמש ב-WorkManager. אפשר גם להוסיף לוגיקה של תזמון מחדש ל-ACTION_BOOT_COMPLETED broadcast receiver, שמופעל כשהאפליקציה יוצאת ממצב שינה וכשהמכשיר מופעל.

שימוש באפליקציות

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

דוגמאות לשימוש באפליקציות

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

ב-Android 11 ואילך, גם ההתנהגויות הבאות נחשבות לאינטראקציות של משתמשים:

  • המשתמש יוצר אינטראקציה עם ווידג'ט.
  • המשתמש יוצר אינטראקציה עם ההתראה, חוץ מסגירת ההתראה.

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

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

דוגמאות לא טובות

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

פטורים של המערכת ממצב שינה

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

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

משתמשים שמוחרגים ממצב שינה

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

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

כדי לבקש פטור, צריך לבצע את השלבים בקטעים הבאים.

בודקים אם המשתמש כבר השבית את התרדמה באפליקציה

כדי לבדוק אם המשתמש כבר השבית את התרדום באפליקציה שלכם, צריך להשתמש ב-API‏ getUnusedAppRestrictionsStatus().

לפרטים נוספים על השימוש ב-API הזה באפליקציה, אפשר לעיין בדוגמת הקוד של ה-API בדף הזה.

בקשה מהמשתמש להשבית את מצב השינה החורף באפליקציה

אם המשתמש לא השבית את התרדמה באפליקציה, אפשר לשלוח לו בקשה. כדי לעשות זאת, מבצעים את השלבים הבאים:

  1. הצגת ממשק משתמש שמסביר למשתמש למה הוא צריך להשבית את מצב השינה החורפית באפליקציה.
  2. מפעילים את createManageUnusedAppRestrictionsIntent() API, כמו שמוצג בדוגמת הקוד של ה-API. ממשק ה-API הזה יוצר intent שמעלה את המסך פרטי האפליקציה בהגדרות. בשלב הזה, המשתמש יכול להשבית את התרדמה של האפליקציה.

    חשוב להתקשר למספר startActivityForResult() ולא למספר startActivity() כששולחים את הכוונה הזו.

    כפי שמוצג בטבלה 2, המיקום והשם של האפשרות תלויים במאפיינים של המכשיר שבו האפליקציה מותקנת:

    טבלה 2. אפשרות להשבית את מצב התנומה באפליקציה
    מאפייני המכשיר הדף שבו האפשרות מופיעה שם האפשרות שרוצים להשבית
    מערכת Android מגרסה 13 ואילך נתונים מאפליקציות השהיית הפעילות באפליקציה אם אין בה שימוש
    מריץ את Android 12 נתונים מאפליקציות הסרת הרשאות ופינוי נפח אחסון
    פועל ב-Android 11 פרטי האפליקציה > הרשאות הסרת ההרשאות כשלא בשימוש
    פועל ב-Android מגרסה 6.0 עד גרסה 10, כולל, ומופעל על ידי Google Play Services אפליקציית Play > תפריט > Play Protect > הרשאות לאפליקציות שלא נעשה בהן שימוש הסרת ההרשאות כשלא בשימוש

קוד לדוגמה ל-API

בדוגמה הזו של קוד אפשר לראות איך בודקים אם מצב שינה מופעל באפליקציה, ומהי הדרך הנכונה לבקש מהמשתמשים להשבית את מצב השינה באפליקציה.

Kotlin

val future: ListenableFuture<Int> =
    PackageManagerCompat.getUnusedAppRestrictionsStatus(context)
future.addListener({ onResult(future.get()) }, ContextCompat.getMainExecutor(context))

fun onResult(appRestrictionsStatus: Int) {
  when (appRestrictionsStatus) {
    // Couldn't fetch status. Check logs for details.
    ERROR -> { }

    // Restrictions don't apply to your app on this device.
    FEATURE_NOT_AVAILABLE -> { }

    // The user has disabled restrictions for your app.
    DISABLED -> { }

    // If the user doesn't start your app for a few months, the system will
    // place restrictions on it. See the API_* constants for details.
    API_30_BACKPORT, API_30, API_31 -> handleRestrictions(appRestrictionsStatus)
  }
}

fun handleRestrictions(appRestrictionsStatus: Int) {
  // If your app works primarily in the background, you can ask the user
  // to disable these restrictions. Check if you have already asked the
  // user to disable these restrictions. If not, you can show a message to
  // the user explaining why permission auto-reset or app hibernation should be
  // disabled. Then, redirect the user to the page in system settings where they
  // can disable the feature.
  val intent = IntentCompat.createManageUnusedAppRestrictionsIntent(context, packageName)

  // You must use startActivityForResult(), not startActivity(), even if
  // you don't use the result code returned in onActivityResult().
  startActivityForResult(intent, REQUEST_CODE)
}

Legacy platform API

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

אם אתם צריכים להמשיך להשתמש ב-API באופן זמני למטרות תאימות, הרשימה הבאה מראה איך להשתמש בו:

הפעלת מצב שינה באופן ידני

כדי לבדוק איך האפליקציה מתנהגת אחרי שהמערכת מעבירה אותה למצב שינה, מבצעים את השלבים הבאים:

  1. (ב-Android מגרסה 12 ואילך בלבד) מפעילים את התנהגות ההיברנציה במכשיר:

    adb shell device_config put app_hibernation app_hibernation_enabled true
    
  2. מגדירים את משך הזמן שבו המערכת ממתינה לפני שהיא עוברת למצב שינה. כך תוכלו לשחזר אותו אחרי הבדיקה:

    threshold=$(adb shell device_config get permissions \
      auto_revoke_unused_threshold_millis2)
    
  3. לקצר את משך הזמן שהמערכת ממתינה. בדוגמה הבאה, המערכת משתנה כך שהאפליקציה נכנסת למצב שינה שנייה אחת בלבד אחרי שמפסיקים את האינטראקציה עם האפליקציה:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  4. ממתינים עד ששידורים בזמן האתחול יסתיימו במכשיר הבדיקה על ידי הרצת הפקודה הבאה:

    adb shell am wait-for-broadcast-idle
    

    בסיום השידורים, הפקודה מחזירה את ההודעה: All broadcast queues are idle!

  5. מפעילים את תהליך התנומה של האפליקציה באופן ידני:

    adb shell cmd jobscheduler run -u 0 -f \
      com.google.android.permissioncontroller 2
    
  6. (ב-Android מגרסה 12 ואילך בלבד) מוודאים שהאפליקציה נמצאת במצב שינה, באחת מהשיטות הבאות:

    • שימו לב שבמכשיר הבדיקה מוצגת עכשיו התראה שמציינת שאפליקציות שלא נעשה בהן שימוש נמצאות במצב שינה.
    • מריצים את הפקודה הבאה:

      adb shell cmd app_hibernation get-state PACKAGE-NAME
      
  7. שחזור ברירת המחדל של משך הזמן שהמערכת ממתינה לפני שהיא מעבירה את האפליקציה למצב שינה:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold