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

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

ההשלכות של מצב שינה

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

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

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

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

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

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

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

ההרשאות בתחילת ההפעלה של האפליקציה יאופסו.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

דוגמאות לא רלוונטיות

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    חשוב להפעיל את startActivityForResult(), ולא את startActivity(), כששולחים את ה-Intent הזה.

    כפי שמוצג בטבלה 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 and higher only) Confirm that the app is hibernated, using one of the following methods:

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

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

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold