บริการที่ทำงานอยู่เบื้องหน้าจะดำเนินการที่ผู้ใช้สังเกตเห็นได้
บริการที่ทำงานอยู่เบื้องหน้าจะแสดงการแจ้งเตือนในแถบสถานะเพื่อให้ผู้ใช้ทราบว่าแอปของคุณกำลังทำงานอยู่เบื้องหน้าและใช้ทรัพยากรของระบบ
ตัวอย่างแอปที่ใช้บริการที่ทำงานอยู่เบื้องหน้า ได้แก่
- แอปเพลเยอร์เพลงที่เล่นเพลงในบริการที่ใช้งานอยู่ การแจ้งเตือนอาจแสดงเพลงที่เล่นอยู่ในปัจจุบัน
- แอปฟิตเนสที่บันทึกการวิ่งของผู้ใช้ในบริการที่ทำงานอยู่เบื้องหน้าหลังจากได้รับสิทธิ์จากผู้ใช้ การแจ้งเตือนอาจแสดงระยะทาง ที่ผู้ใช้ได้เดินทางในระหว่างเซสชันการออกกำลังกายปัจจุบัน
ใช้บริการที่ทำงานอยู่เบื้องหน้าก็ต่อเมื่อแอปต้องทำงานให้ผู้ใช้เห็น แม้ว่าผู้ใช้ไม่ได้โต้ตอบกับแอปโดยตรงก็ตาม หากการดำเนินการมีความสําคัญต่ำมากจนคุณต้องการใช้การแจ้งเตือนที่มีลําดับความสําคัญต่ำ ให้สร้างงานในเบื้องหลังแทน
เอกสารนี้อธิบายสิทธิ์ที่จําเป็นสําหรับการใช้บริการที่ทํางานอยู่เบื้องหน้า ตลอดจนวิธีเริ่มบริการที่ทํางานอยู่เบื้องหน้าและนําออกจากเบื้องหลัง นอกจากนี้ยังอธิบายวิธีเชื่อมโยงกรณีการใช้งานบางอย่างกับประเภทบริการที่ทำงานอยู่เบื้องหน้า และข้อจํากัดการเข้าถึงที่จะมีผลเมื่อคุณเริ่มบริการที่ทำงานอยู่เบื้องหน้าจากแอปที่ทำงานอยู่เบื้องหลัง
ผู้ใช้สามารถปิดการแจ้งเตือนโดยค่าเริ่มต้น
ตั้งแต่ Android 13 (API ระดับ 33) เป็นต้นไป ผู้ใช้จะปิดการแจ้งเตือนที่เชื่อมโยงกับบริการที่ทำงานอยู่เบื้องหน้าได้โดยค่าเริ่มต้น โดยผู้ใช้ใช้ท่าทางสัมผัสปัดในการแจ้งเตือน โดยทั่วไปแล้ว การแจ้งเตือนจะยังไม่หายไป เว้นแต่ว่าบริการที่ทำงานอยู่เบื้องหน้าจะหยุดหรือนำออกจากเบื้องหน้า
หากไม่ต้องการให้ผู้ใช้ปิดการแจ้งเตือนได้ ให้ส่ง true
ไปยังเมธอด setOngoing()
เมื่อสร้างการแจ้งเตือนโดยใช้ Notification.Builder
บริการที่แสดงการแจ้งเตือนทันที
หากบริการที่ทำงานอยู่เบื้องหน้ามีลักษณะต่อไปนี้อย่างน้อย 1 ข้อ ระบบจะแสดงการแจ้งเตือนที่เกี่ยวข้องทันทีที่บริการเริ่มทำงาน แม้แต่ในอุปกรณ์ที่ใช้ Android 12 ขึ้นไป
- บริการเชื่อมโยงกับการแจ้งเตือนที่มีปุ่มการทำงาน
- บริการมี
foregroundServiceType
mediaPlayback
,mediaProjection
หรือphoneCall
- บริการนี้มีกรณีการใช้งานที่เกี่ยวข้องกับการโทร การนำทาง หรือการเพลย์แบ็กสื่อตามที่ระบุไว้ในแอตทริบิวต์หมวดหมู่ของการแจ้งเตือน
- บริการเลือกไม่ใช้การเปลี่ยนแปลงลักษณะการทำงานโดยส่ง
FOREGROUND_SERVICE_IMMEDIATE
ไปยังsetForegroundServiceBehavior()
เมื่อตั้งค่าการแจ้งเตือน
ใน Android 13 (API ระดับ 33) ขึ้นไป หากผู้ใช้ปฏิเสธสิทธิ์การแจ้งเตือน ผู้ใช้จะยังคงเห็นการแจ้งเตือนที่เกี่ยวข้องกับบริการที่ทำงานอยู่เบื้องหน้าในตัวจัดการงาน แต่จะไม่เห็นการแจ้งเตือนในลิ้นชักการแจ้งเตือน
ประกาศบริการที่ทำงานอยู่เบื้องหน้าในไฟล์ Manifest
ในไฟล์ Manifest ของแอป ให้ประกาศบริการที่ทำงานอยู่เบื้องหน้าของแอปแต่ละรายการด้วยองค์ประกอบ <service>
สําหรับบริการแต่ละรายการ ให้ใช้แอตทริบิวต์ android:foregroundServiceType
เพื่อประกาศประเภทของงานที่บริการทํา
ตัวอย่างเช่น หากแอปสร้างบริการที่ทำงานอยู่เบื้องหน้าซึ่งเปิดเพลง คุณอาจประกาศบริการดังนี้
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<application ...>
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="false">
</service>
</application>
</manifest>
หากบริการของคุณมีประเภทหลายประเภท ให้คั่นด้วยโอเปอเรเตอร์ |
ตัวอย่างเช่น บริการที่ใช้กล้องและไมโครโฟนจะประกาศดังนี้
android:foregroundServiceType="camera|microphone"
ขอสิทธิ์บริการที่ทำงานอยู่เบื้องหน้า
แอปที่กำหนดเป้าหมายเป็น Android 9 (API ระดับ 28) ขึ้นไปและใช้บริการที่ทำงานอยู่เบื้องหน้าต้องขอ FOREGROUND_SERVICE
ในไฟล์ Manifest ของแอปดังที่แสดงในข้อมูลโค้ดต่อไปนี้ นี่เป็นสิทธิ์ปกติ ดังนั้นระบบจึงให้สิทธิ์กับแอปที่ขอโดยอัตโนมัติ
นอกจากนี้ หากแอปกำหนดเป้าหมายเป็น API ระดับ 34 ขึ้นไป แอปจะต้องขอสิทธิ์ประเภทที่เหมาะสมกับประเภทของงานที่บริการที่ทำงานอยู่เบื้องหน้าจะทำ บริการที่ทำงานอยู่เบื้องหน้าแต่ละประเภทมีสิทธิ์ประเภทหนึ่งๆ ที่เกี่ยวข้อง เช่น หากแอปเปิดใช้บริการที่ทำงานอยู่เบื้องหน้าที่ใช้กล้อง คุณจะต้องขอสิทธิ์ทั้ง FOREGROUND_SERVICE
และ FOREGROUND_SERVICE_CAMERA
สิทธิ์เหล่านี้เป็นสิทธิ์ปกติทั้งหมด ดังนั้นระบบจึงให้สิทธิ์โดยอัตโนมัติหากระบุไว้ในไฟล์ Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA"/>
<application ...>
...
</application>
</manifest>
ข้อกําหนดเบื้องต้นของบริการที่ทำงานอยู่เบื้องหน้า
ตั้งแต่ Android 14 (API ระดับ 34) เป็นต้นไป เมื่อคุณเปิดบริการที่ทำงานอยู่เบื้องหน้า ระบบจะตรวจสอบข้อกําหนดเบื้องต้นที่เฉพาะเจาะจงตามประเภทบริการ ตัวอย่างเช่น หากคุณพยายามเปิดบริการที่ทำงานอยู่เบื้องหน้าประเภท location
ระบบจะตรวจสอบว่าแอปของคุณมีสิทธิ์ ACCESS_COARSE_LOCATION
หรือ ACCESS_FINE_LOCATION
อยู่แล้ว หากไม่ ระบบจะแสดงข้อผิดพลาด SecurityException
ด้วยเหตุนี้ คุณจึงต้องยืนยันว่ามีคุณสมบัติตรงตามข้อกำหนดเบื้องต้นที่จำเป็นก่อนจะเริ่มบริการที่ทำงานอยู่เบื้องหน้า เอกสารประกอบเกี่ยวกับประเภทบริการที่ทำงานอยู่เบื้องหน้าจะแสดงรายการข้อกําหนดเบื้องต้นที่จําเป็นสําหรับบริการที่ทำงานอยู่เบื้องหน้าแต่ละประเภท
เริ่มบริการที่ทำงานอยู่เบื้องหน้า
ก่อนขอให้ระบบเรียกใช้บริการเป็นบริการเบื้องหน้า ให้เริ่มบริการนั้นเองโดยทำดังนี้
Kotlin
val intent = Intent(...) // Build the intent for the service context.startForegroundService(intent)
Java
Context context = getApplicationContext(); Intent intent = new Intent(...); // Build the intent for the service context.startForegroundService(intent);
คุณสามารถขอให้บริการทำงานอยู่เบื้องหน้าได้ภายในบริการ ซึ่งโดยปกติจะอยู่ใน onStartCommand()
โดยเรียกใช้ ServiceCompat.startForeground()
(ใช้ได้ใน androidx-core 1.12 ขึ้นไป) เมธอดนี้ใช้พารามิเตอร์ต่อไปนี้
- บริการ
- จำนวนเต็มบวกที่ระบุการแจ้งเตือนในแถบสถานะอย่างเจาะจง
- ออบเจ็กต์
Notification
เอง - ประเภทบริการที่ทำงานอยู่เบื้องหน้า ระบุงานที่บริการทำ
ประเภทเหล่านี้อาจเป็นชุดย่อยของประเภทที่ประกาศในไฟล์ Manifest โดยขึ้นอยู่กับ Use Case ที่เฉพาะเจาะจง จากนั้นหากต้องการเพิ่มบริการประเภทอื่นๆ ให้โทรไปที่ startForeground()
อีกครั้ง
ตัวอย่างเช่น สมมติว่าแอปฟิตเนสเรียกใช้บริการติดตามการวิ่งที่ต้องใช้ข้อมูล location
เสมอ แต่อาจหรือไม่ต้องการเปิดสื่อ คุณจะต้องประกาศทั้ง location
และ mediaPlayback
ในไฟล์ Manifest หากผู้ใช้เริ่มการวิ่งและต้องการแค่การติดตามตำแหน่ง แอปของคุณควรเรียกใช้ startForeground()
และส่งเฉพาะสิทธิ์ ACCESS_FINE_LOCATION
จากนั้นหากผู้ใช้ต้องการเริ่มเล่นเสียง ให้เรียก startForeground()
อีกครั้งและส่งค่าผสมแบบบิตของบริการที่ทำงานอยู่เบื้องหน้าทุกประเภท (ในกรณีนี้คือ ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK
)
นี่คือตัวอย่างที่เปิดใช้บริการที่ทำงานอยู่เบื้องหน้าของกล้อง
Kotlin
class MyCameraService: Service() { private fun startForeground() { // Before starting the service as foreground check that the app has the // appropriate runtime permissions. In this case, verify that the user has // granted the CAMERA permission. val cameraPermission = PermissionChecker.checkSelfPermission(this, Manifest.permission.CAMERA) if (cameraPermission != PermissionChecker.PERMISSION_GRANTED) { // Without camera permissions the service cannot run in the foreground // Consider informing user or updating your app UI if visible. stopSelf() return } try { val notification = NotificationCompat.Builder(this, "CHANNEL_ID") // Create the notification to display while the service is running .build() ServiceCompat.startForeground( /* service = */ this, /* id = */ 100, // Cannot be 0 /* notification = */ notification, /* foregroundServiceType = */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA } else { 0 }, ) } catch (e: Exception) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e is ForegroundServiceStartNotAllowedException) { // App not in a valid state to start foreground service // (e.g. started from bg) } // ... } } }
Java
public class MyCameraService extends Service { private void startForeground() { // Before starting the service as foreground check that the app has the // appropriate runtime permissions. In this case, verify that the user // has granted the CAMERA permission. int cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA); if (cameraPermission == PackageManager.PERMISSION_DENIED) { // Without camera permissions the service cannot run in the // foreground. Consider informing user or updating your app UI if // visible. stopSelf(); return; } try { Notification notification = new NotificationCompat.Builder(this, "CHANNEL_ID") // Create the notification to display while the service // is running .build(); int type = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { type = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; } ServiceCompat.startForeground( /* service = */ this, /* id = */ 100, // Cannot be 0 /* notification = */ notification, /* foregroundServiceType = */ type ); } catch (Exception e) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e instanceof ForegroundServiceStartNotAllowedException ) { // App not in a valid state to start foreground service // (e.g started from bg) } // ... } } //... }
นำบริการออกจากเบื้องหน้า
หากต้องการนำบริการออกจากเบื้องหน้า ให้เรียกใช้ stopForeground()
วิธีนี้ใช้บูลีนซึ่งระบุว่าจะนำการแจ้งเตือนบนแถบสถานะออกด้วยหรือไม่ โปรดทราบว่าบริการจะยังคงทำงานต่อไป
หากคุณหยุดบริการขณะที่บริการทำงานอยู่เบื้องหน้า ระบบจะนำการแจ้งเตือนของบริการนั้นออก
จัดการการหยุดแอปที่เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าซึ่งเริ่มต้นโดยผู้ใช้
ตั้งแต่ Android 13 (API ระดับ 33) เป็นต้นไป ผู้ใช้สามารถทำตามเวิร์กโฟลว์จากลิ้นชักการแจ้งเตือนเพื่อหยุดแอปที่มีบริการที่ทำงานอยู่เบื้องหน้าได้ ไม่ว่า SDK เป้าหมายของแอปนั้นจะเวอร์ชันใดก็ตาม สิ่งอำนวยความสะดวกนี้เรียกว่าตัวจัดการงาน ซึ่งจะแสดงรายการแอปที่กําลังเรียกใช้บริการที่ทำงานอยู่เบื้องหน้า
รายการนี้มีป้ายกำกับว่าแอปที่ใช้งานอยู่ ข้างแต่ละแอปจะมีปุ่มหยุด รูปที่ 1 แสดงเวิร์กโฟลว์ของตัวจัดการงานบนอุปกรณ์ที่ใช้ Android 13
เมื่อผู้ใช้กดปุ่มหยุดข้างแอปของคุณในเครื่องมือจัดการงาน ระบบจะดำเนินการต่อไปนี้
- ระบบจะนำแอปออกจากหน่วยความจำ ดังนั้น ทั้งแอปจะหยุดทำงาน ไม่ใช่แค่บริการที่ทำงานอยู่เบื้องหน้า
- ระบบจะนำกองซ้อนย้อนกลับของกิจกรรมของแอปออก
- การเล่นสื่อจะหยุดลง
- ระบบจะนำการแจ้งเตือนที่เชื่อมโยงกับบริการที่ทำงานอยู่เบื้องหน้าออก
- แอปจะยังคงอยู่ในประวัติ
- งานที่กำหนดเวลาไว้จะทำงานตามเวลาที่กำหนดไว้
- การปลุกจะดังขึ้นตามเวลาหรือกรอบเวลาที่กําหนดไว้
REASON_USER_REQUESTED
หากต้องการทดสอบว่าแอปทำงานตามที่คาดไว้ขณะและหลังจากที่ผู้ใช้หยุดแอป ให้เรียกใช้คำสั่ง ADB ต่อไปนี้ในหน้าต่างเทอร์มินัล
adb shell cmd activity stop-app PACKAGE_NAME
การยกเว้น
ระบบมีการยกเว้นหลายระดับสำหรับแอปบางประเภท ตามที่อธิบายไว้ในส่วนต่อไปนี้
การยกเว้นจะเป็นไปตามแอป ไม่ใช่ตามกระบวนการ หากระบบยกเว้นกระบวนการหนึ่งในแอป กระบวนการอื่นๆ ทั้งหมดในแอปนั้นก็จะได้รับยกเว้นด้วย
การยกเว้นไม่ให้ปรากฏในตัวจัดการงานเลย
แอปต่อไปนี้เรียกใช้บริการที่ทำงานอยู่เบื้องหน้าได้และไม่ปรากฏในตัวจัดการงานเลย
- แอประดับระบบ
- แอปความปลอดภัย ซึ่งก็คือแอปที่มีบทบาท
ROLE_EMERGENCY
- อุปกรณ์ที่อยู่ในโหมดสาธิต
ข้อยกเว้นที่ผู้ใช้ไม่สามารถหยุดได้
เมื่อแอปประเภทต่อไปนี้เรียกใช้บริการที่ทำงานอยู่เบื้องหน้า แอปจะปรากฏในเครื่องมือจัดการงาน แต่จะไม่มีปุ่มหยุดข้างชื่อแอปให้ผู้ใช้แตะ
- แอปเจ้าของอุปกรณ์
- เจ้าของโปรไฟล์ แอป
- แอปถาวร
- แอปที่มีบทบาท
ROLE_DIALER
ใช้ API ที่สร้างขึ้นเพื่อวัตถุประสงค์เฉพาะแทนบริการที่ทำงานอยู่เบื้องหน้า
สําหรับ Use Case หลายรายการ มี API ของแพลตฟอร์มหรือ Jetpack ที่คุณสามารถใช้เพื่อทํางานต่างๆ ได้ ซึ่งปกติแล้วคุณอาจใช้บริการที่ทำงานอยู่เบื้องหน้า หากมี API ที่สร้างตามวัตถุประสงค์ที่เหมาะสม คุณควรใช้ API ดังกล่าวแทนที่จะใช้บริการที่ทำงานอยู่เบื้องหน้าเกือบทุกครั้ง API ที่สร้างตามวัตถุประสงค์มักจะมีความสามารถเฉพาะกรณีการใช้งานเพิ่มเติม ซึ่งคุณไม่จำเป็นต้องสร้างเพิ่มเอง ตัวอย่างเช่น Bubbles API จะจัดการตรรกะ UI ที่ซับซ้อนสําหรับแอปรับส่งข้อความที่ต้องติดตั้งใช้งานฟีเจอร์ฟองข้อความ
เอกสารประกอบสำหรับประเภทบริการที่ทำงานอยู่เบื้องหน้าจะแสดงทางเลือกที่ดีในการใช้แทนบริการที่ทำงานอยู่เบื้องหน้า
ข้อจำกัดในการเริ่มบริการที่ทำงานอยู่เบื้องหน้าจากเบื้องหลัง
แอปที่กำหนดเป้าหมายเป็น Android 12 ขึ้นไปจะไม่สามารถเริ่มบริการที่ทำงานอยู่เบื้องหน้าขณะที่แอปทำงานอยู่เบื้องหลัง ยกเว้นบางกรณีพิเศษ หากแอปพยายามเริ่มบริการที่ทำงานอยู่เบื้องหน้าขณะที่แอปทำงานอยู่เบื้องหลัง และบริการที่ทำงานอยู่เบื้องหน้าไม่ตรงกับกรณียกเว้นข้อใดข้อหนึ่ง ระบบจะแสดงForegroundServiceStartNotAllowedException
นอกจากนี้ หากแอปต้องการเปิดบริการที่ทำงานอยู่เบื้องหน้าซึ่งต้องใช้สิทธิ์ขณะใช้งาน (เช่น สิทธิ์เข้าถึงเซ็นเซอร์ร่างกาย กล้อง ไมโครโฟน หรือตำแหน่ง) แอปจะสร้างบริการดังกล่าวไม่ได้ขณะที่แอปทำงานอยู่เบื้องหลัง แม้ว่าแอปจะอยู่ในข้อยกเว้นข้อใดข้อหนึ่งจากการจำกัดการเริ่มทำงานในเบื้องหลังก็ตาม เหตุผลมีคำอธิบายอยู่ในส่วนข้อจำกัดในการเริ่มบริการที่ทำงานอยู่เบื้องหน้าซึ่งต้องมีสิทธิ์ขณะใช้งาน
ข้อยกเว้นจากข้อจำกัดการเริ่มต้นทำงานในเบื้องหลัง
ในกรณีต่อไปนี้ แอปสามารถเริ่มบริการที่ทำงานอยู่เบื้องหน้าได้แม้ว่าแอปจะทำงานอยู่เบื้องหลังก็ตาม
- แอปของคุณเปลี่ยนจากสถานะที่ผู้ใช้มองเห็นได้ เช่น กิจกรรม
- แอปสามารถเริ่มกิจกรรมจากเบื้องหลังได้ ยกเว้นในกรณีที่แอปมีกิจกรรมในกองซ้อนด้านหลังของงานที่มีอยู่
แอปของคุณได้รับข้อความที่มีลําดับความสําคัญสูงโดยใช้ Firebase Cloud Messaging
ผู้ใช้ดำเนินการกับองค์ประกอบ UI ที่เกี่ยวข้องกับแอปของคุณ เช่น ผู้ใช้อาจโต้ตอบกับลูกโป่ง การแจ้งเตือน วิดเจ็ต หรือกิจกรรม
แอปเรียกใช้การปลุกในเวลาที่แน่นอนเพื่อดำเนินการตามที่ผู้ใช้ขอ
แอปของคุณเป็นวิธีการป้อนข้อมูลปัจจุบันของอุปกรณ์
แอปของคุณได้รับเหตุการณ์ที่เกี่ยวข้องกับการกำหนดเขตพื้นที่เสมือนหรือการเปลี่ยนสถานะการจดจำกิจกรรม
หลังจากอุปกรณ์รีบูตและได้รับการดำเนินการตามความตั้งใจ
ACTION_BOOT_COMPLETED
,ACTION_LOCKED_BOOT_COMPLETED
หรือACTION_MY_PACKAGE_REPLACED
ในBroadcast Receiverแอปของคุณได้รับการดำเนินการตามเจตนา
ACTION_TIMEZONE_CHANGED
,ACTION_TIME_CHANGED
หรือACTION_LOCALE_CHANGED
ใน Broadcast Receiverแอปของคุณได้รับเหตุการณ์
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()
เพื่อตรวจสอบว่ามีสิทธิ์ดังกล่าวหรือไม่ วิธีการจะแสดงผลเป็น 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