הגבלות על הפעלת שירות שפועל בחזית מהרקע

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

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

חריגים להגבלות על הפעלה מהרקע

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

הגבלות על הפעלה של שירותים שפועלים בחזית ודורשים הרשאות לשימוש בזמן שהאפליקציה פתוחה

ב-Android 14 (רמת API 34) ומעלה, יש מצבים מיוחדים שחשוב להכיר אם מפעילים שירות שפועל בחזית וצריך הרשאות לשימוש בזמן שהאפליקציה פועלת.

אם האפליקציה שלכם מטרגטת ל-Android 14 ואילך, מערכת ההפעלה בודקת כשאתם יוצרים שירות שפועל בחזית כדי לוודא שיש לאפליקציה את כל ההרשאות המתאימות לסוג השירות הזה. לדוגמה, כשיוצרים שירות שפועל בחזית מסוג microphone, מערכת ההפעלה מוודאת שלאפליקציה יש כרגע את ההרשאה RECORD_AUDIO. אם אין לכם את ההרשאה הזו, המערכת תציג את השגיאה SecurityException.

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

באופן דומה, אם האפליקציה פועלת ברקע והיא יוצרת שירות בריאות שזקוק להרשאה BODY_SENSORS, לאפליקציה אין כרגע את ההרשאה הזו והמערכת יוצרת חריגה. (ההגדרה הזו לא רלוונטית אם מדובר בשירות בריאות שדורש הרשאות שונות, כמו ACTIVITY_RECOGNITION.) התקשרות אל PermissionChecker.checkSelfPermission() לא תמנע את הבעיה הזו. אם לאפליקציה יש הרשאה לשימוש בזמן שהיא פועלת, והיא קוראת ל-checkSelfPermission() כדי לבדוק אם יש לה את ההרשאה הזו, הפונקציה מחזירה PERMISSION_GRANTED גם אם האפליקציה פועלת ברקע. אם השיטה מחזירה PERMISSION_GRANTED, המשמעות היא שהאפליקציה קיבלה את ההרשאה בזמן השימוש באפליקציה.

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

חריגים מההגבלות על הרשאות בזמן השימוש

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

באותם מצבים, אם השירות מצהיר על סוג של שירות שפועל בחזית מסוג 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