אפליקציות שמטרגטות ל-Android 12 (רמת API 31) ומעלה לא יכולות להפעיל שירותים בחזית כשהאפליקציה פועלת ברקע, למעט כמה מקרים מיוחדים. אם אפליקציה מנסה להפעיל שירות שפועל בחזית בזמן שהיא פועלת ברקע, והשירות לא עומד באחד מהתנאים של מקרי החריגה, המערכת מקפיצה את השגיאה ForegroundServiceStartNotAllowedException.
בנוסף, אם אפליקציה רוצה להפעיל שירות שפועל בחזית ודורש הרשאות בזמן השימוש (לדוגמה, הרשאות גישה לחיישנים גופניים, למצלמה, למיקרופון או למיקום), היא לא יכולה ליצור את השירות כשהיא פועלת ברקע, גם אם היא עומדת באחד מהתנאים לפטור מההגבלות על הפעלה ברקע. הסיבה לכך מוסברת בקטע הגבלות על הפעלת שירותים שפועלים בחזית ודורשים הרשאות "בזמן השימוש".
פטורים מהגבלות על הפעלה ברקע
במצבים הבאים, האפליקציה יכולה להפעיל שירותים שפועלים בחזית גם כשהיא פועלת ברקע:
- האפליקציה עוברת ממצב שגלוי למשתמש, כמו פעילות.
- האפליקציה יכולה להתחיל פעילות מהרקע, חוץ ממקרים שבהם יש לאפליקציה פעילות במקבץ הפעילויות הקודמות (back stack) של משימה קיימת.
האפליקציה מקבלת הודעה בעדיפות גבוהה באמצעות העברת הודעות בענן ב-Firebase.
המשתמש מבצע פעולה ברכיב בממשק המשתמש שקשור לאפליקציה. לדוגמה, הוא יכול לבצע אינטראקציה עם בועה, התראה, ווידג'ט או פעילות.
האפליקציה מפעילה משימה ברגע מדויק כדי להשלים פעולה שהמשתמש ביקש.
האפליקציה שלכם היא שיטת הקלט הנוכחית של המכשיר.
האפליקציה מקבלת אירוע שקשור לגבולות וירטואליים או למעבר בין פעילויות.
אחרי שהמכשיר מופעל מחדש ומקבל את פעולת ה-intent
ACTION_BOOT_COMPLETED,ACTION_LOCKED_BOOT_COMPLETEDאוACTION_MY_PACKAGE_REPLACEDבמקלט שידור.האפליקציה מקבלת את פעולת ה-Intent
ACTION_TIMEZONE_CHANGED,ACTION_TIME_CHANGEDאוACTION_LOCALE_CHANGEDבמקלט שידור.האפליקציה מקבלת את האירוע
ACTION_TRANSACTION_DETECTEDמ-NfcService.אפליקציות עם תפקידים או הרשאות מסוימים במערכת, כמו בעלי מכשירים ובעלי פרופילים.
האפליקציה משתמשת בשיוך של מכשירים לאפליקציות נלוות ומצהירה על ההרשאה
REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUNDאו על ההרשאהREQUEST_COMPANION_RUN_IN_BACKGROUND. כשאפשר, כדאי להשתמש ב-REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND.המשתמש משבית את האופטימיזציה של הסוללה באפליקציה.
לאפליקציה יש את ההרשאה
SYSTEM_ALERT_WINDOW. הערה: אם האפליקציה מטרגטת את Android מגרסה 15 ואילך, צריכה להיות לה ההרשאהSYSTEM_ALERT_WINDOWוגם חלון שכבת-על גלוי.
הגבלות על הפעלת שירותים שפועלים בחזית ודורשים הרשאות "בזמן השימוש"
ב-Android 14 (רמת API 34) ואילך, יש מצבים מיוחדים שצריך לשים לב אליהם אם מפעילים שירות שפועל בחזית ודורש הרשאות בזמן השימוש.
אם האפליקציה שלכם מטרגטת את Android מגרסה 14 ואילך, מערכת ההפעלה בודקת כשאתם יוצרים שירות שפועל בחזית כדי לוודא שיש לאפליקציה את כל ההרשאות המתאימות לסוג השירות הזה. לדוגמה, כשיוצרים שירות שפועל בחזית מסוג מיקרופון, מערכת ההפעלה מוודאת שלאפליקציה יש כרגע את ההרשאה RECORD_AUDIO. אם אין לכם את ההרשאה הזו, המערכת תציג את השגיאה SecurityException.
בהרשאות שניתנות בזמן השימוש, זה עלול לגרום לבעיה. אם לאפליקציה יש הרשאה לשימוש בזמן שהיא פועלת, יש לה את ההרשאה הזו רק כשהיא פועלת בחזית. כלומר, אם האפליקציה פועלת ברקע ומנסה ליצור שירות שפועל בחזית מסוג מצלמה, מיקום או מיקרופון, המערכת מזהה שלאפליקציה אין כרגע את ההרשאות הנדרשות, ומופיעה השגיאה SecurityException.
באופן דומה, אם האפליקציה פועלת ברקע ויוצרת שירות בריאות שצריך את ההרשאה BODY_SENSORS, לאפליקציה אין כרגע את ההרשאה הזו, והמערכת מקפיצה חריגה.
(זה לא רלוונטי אם מדובר בשירות בריאות שדורש הרשאות שונות, כמו ACTIVITY_RECOGNITION). קריאה ל-PermissionChecker.checkSelfPermission() לא מונעת את הבעיה הזו. אם לאפליקציה יש הרשאה לשימוש בזמן שהיא פועלת, והיא קוראת ל-checkSelfPermission() כדי לבדוק אם יש לה את ההרשאה הזו, ה-method מחזירה את הערך PERMISSION_GRANTED גם אם האפליקציה פועלת ברקע. כשהשיטה מחזירה את הערך PERMISSION_GRANTED, המשמעות היא "לאפליקציה יש את ההרשאה הזו בזמן שהאפליקציה בשימוש".
לכן, אם השירות שפועל בחזית צריך הרשאה לשימוש באפליקציה, צריך להפעיל את Context.startForegroundService() או את Context.bindService() כשהאפליקציה מציגה פעילות, אלא אם השירות נכלל באחד מהפטורים המוגדרים.
פטורים מהגבלות על הרשאות בזמן השימוש
במצבים מסוימים, גם אם שירות שפועל בחזית מופעל כשהאפליקציה פועלת ברקע, הוא עדיין יכול לגשת למידע על המיקום, המצלמה והמיקרופון כשהאפליקציה פועלת בחזית ("בזמן השימוש").
באותם מצבים, אם השירות מצהיר על סוג שירות שפועל בחזית של location ומופעל על ידי אפליקציה עם ההרשאה ACCESS_BACKGROUND_LOCATION, השירות הזה יכול לגשת לנתוני המיקום כל הזמן, גם כשהאפליקציה פועלת ברקע.
הרשימה הבאה כוללת את המצבים האלה:
- רכיב מערכת מפעיל את השירות.
- השירות מתחיל באינטראקציה עם ווידג'טים של אפליקציות.
- השירות מתחיל באינטראקציה עם התראה.
- השירות מתחיל כ-
PendingIntentשנשלח מאפליקציה אחרת שגלויה למשתמש. - השירות מופעל על ידי אפליקציה שהיא בקר מדיניות מכשיר שפועל במצב ניהול ברמת בעלים.
- השירות מופעל על ידי אפליקציה שמספקת את
VoiceInteractionService. - השירות מופעל על ידי אפליקציה שיש לה את ההרשאה המיוחדת
START_ACTIVITIES_FROM_BACKGROUND.
איך בודקים אילו שירותים מושפעים באפליקציה
כשבודקים את האפליקציה, צריך להפעיל את השירותים שלה שפועלים בחזית. אם לשירות שהופעל יש גישה מוגבלת למיקום, למיקרופון ולמצלמה, ההודעה הבאה מופיעה ב-Logcat:
Foreground service started from background can not have \ location/camera/microphone access: service SERVICE_NAME