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

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

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

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

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

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

ב-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() בזמן שיש פעילות גלויה באפליקציה, אלא אם השירות נכלל באחד מהפטורים המוגדרים.

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

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

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