บริการที่ทำงานอยู่เบื้องหน้า

บริการที่ทำงานอยู่เบื้องหน้าจะดำเนินการที่ผู้ใช้สังเกตเห็นได้

บริการที่ทำงานอยู่เบื้องหน้าจะแสดงการแจ้งเตือนในแถบสถานะเพื่อให้ผู้ใช้ทราบว่าแอปของคุณกำลังทำงานอยู่เบื้องหน้าและใช้ทรัพยากรของระบบ

ตัวอย่างแอปที่ใช้บริการที่ทำงานอยู่เบื้องหน้า ได้แก่

  • แอปเพลเยอร์เพลงที่เล่นเพลงในบริการที่ใช้งานอยู่ การแจ้งเตือนอาจแสดงเพลงที่เล่นอยู่ในปัจจุบัน
  • แอปฟิตเนสที่บันทึกการวิ่งของผู้ใช้ในบริการที่ทำงานอยู่เบื้องหน้าหลังจากได้รับสิทธิ์จากผู้ใช้ การแจ้งเตือนอาจแสดงระยะทางที่ผู้ใช้เดินในระหว่างเซสชันการออกกำลังกายปัจจุบัน

ใช้บริการที่ทำงานอยู่เบื้องหน้าก็ต่อเมื่อแอปต้องทำงานให้ผู้ใช้เห็น แม้ว่าผู้ใช้ไม่ได้โต้ตอบกับแอปโดยตรงก็ตาม หากการดำเนินการมีความสําคัญต่ำมากจนคุณต้องการใช้การแจ้งเตือนที่มีลําดับความสําคัญต่ำ ให้สร้างงานในเบื้องหลังแทน

เอกสารนี้อธิบายสิทธิ์ที่จําเป็นสําหรับการใช้บริการที่ทํางานอยู่เบื้องหน้า ตลอดจนวิธีเริ่มบริการที่ทํางานอยู่เบื้องหน้าและนําออกจากเบื้องหลัง นอกจากนี้ ยังอธิบายวิธีเชื่อมโยง Use Case บางรายการกับประเภทบริการที่ทำงานอยู่เบื้องหน้า และข้อจำกัดการเข้าถึงที่มีผลเมื่อคุณเริ่มบริการที่ทำงานอยู่เบื้องหน้าจากแอปที่ทำงานอยู่เบื้องหลัง

ผู้ใช้ปิดการแจ้งเตือนได้โดยค่าเริ่มต้น

ตั้งแต่ 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 ขึ้นไป) เมธอดนี้ใช้พารามิเตอร์ต่อไปนี้

ประเภทเหล่านี้อาจเป็นชุดย่อยของประเภทที่ประกาศในไฟล์ 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() เมธอดนี้ใช้บูลีน ซึ่งระบุว่าจะนำการแจ้งเตือนในแถบสถานะออกด้วยหรือไม่ โปรดทราบว่าบริการจะยังคงทำงานต่อไป

หากคุณหยุดบริการขณะที่บริการทำงานอยู่เบื้องหน้า ระบบจะนำการแจ้งเตือนของบริการนั้นออก

จัดการการหยุดแอปที่ทำงานอยู่เบื้องหน้าซึ่งผู้ใช้เป็นผู้เริ่ม

ที่ด้านล่างของลิ้นชักการแจ้งเตือนจะมีปุ่มที่ระบุจำนวนแอปที่ทำงานอยู่เบื้องหลัง เมื่อกดปุ่มนี้ กล่องโต้ตอบจะปรากฏขึ้นพร้อมแสดงชื่อแอปต่างๆ ปุ่มหยุดจะอยู่ด้านขวาของแต่ละแอป
รูปที่ 1 เวิร์กโฟลว์ของเครื่องมือจัดการงานในอุปกรณ์ที่ใช้ Android 13 ขึ้นไป

ตั้งแต่ Android 13 (API ระดับ 33) เป็นต้นไป ผู้ใช้สามารถทำตามเวิร์กโฟลว์จากลิ้นชักการแจ้งเตือนเพื่อหยุดแอปที่มีบริการที่ทำงานอยู่เบื้องหน้าได้ ไม่ว่า SDK เป้าหมายของแอปนั้นจะเวอร์ชันใดก็ตาม สิ่งอำนวยความสะดวกนี้เรียกว่าตัวจัดการงาน ซึ่งจะแสดงรายการแอปที่กําลังเรียกใช้บริการที่ทำงานอยู่เบื้องหน้า

รายการนี้มีป้ายกำกับว่าแอปที่ใช้งานอยู่ ข้างแต่ละแอปจะมีปุ่มหยุด รูปที่ 1 แสดงเวิร์กโฟลว์ของเครื่องมือจัดการงานในอุปกรณ์ที่ใช้ Android 13

เมื่อผู้ใช้กดปุ่มหยุดข้างแอปของคุณในเครื่องมือจัดการงาน ระบบจะดำเนินการต่อไปนี้

  • ระบบจะนำแอปออกจากหน่วยความจำ ดังนั้น ทั้งแอปจะหยุดทำงาน ไม่ใช่แค่บริการที่ทำงานอยู่เบื้องหน้า
  • ระบบจะนำกองซ้อนย้อนกลับของกิจกรรมของแอปออก
  • การเล่นสื่อจะหยุดลง
  • ระบบจะนำการแจ้งเตือนที่เชื่อมโยงกับบริการที่ทำงานอยู่เบื้องหน้าออก
  • แอปจะยังคงอยู่ในประวัติ
  • งานที่กำหนดเวลาไว้จะทำงานตามเวลาที่กำหนดไว้
  • การปลุกจะดังขึ้นตามเวลาหรือกรอบเวลาที่กําหนดไว้
ดังนี้ REASON_USER_REQUESTED

หากต้องการทดสอบว่าแอปทำงานตามที่คาดไว้ขณะและหลังจากที่ผู้ใช้หยุดแอป ให้เรียกใช้คำสั่ง ADB ต่อไปนี้ในหน้าต่างเทอร์มินัล

adb shell cmd activity stop-app PACKAGE_NAME

การยกเว้น

ระบบมีการยกเว้นหลายระดับสำหรับแอปบางประเภท ตามที่อธิบายไว้ในส่วนต่อไปนี้

การยกเว้นจะเป็นไปตามแอป ไม่ใช่ตามกระบวนการ หากระบบยกเว้นกระบวนการหนึ่งในแอป กระบวนการอื่นๆ ทั้งหมดในแอปนั้นก็จะได้รับยกเว้นด้วย

ได้รับการยกเว้นไม่ให้ปรากฏใน Task Manager เลย

แอปต่อไปนี้สามารถเรียกใช้บริการที่ทำงานอยู่เบื้องหน้าและจะไม่ปรากฏในตัวจัดการงานเลย

  • แอประดับระบบ
  • แอปความปลอดภัย ซึ่งก็คือแอปที่มีบทบาท ROLE_EMERGENCY
  • อุปกรณ์ที่อยู่ในโหมดสาธิต

ข้อยกเว้นที่ผู้ใช้ไม่สามารถหยุดได้

เมื่อแอปประเภทต่อไปนี้เรียกใช้บริการที่ทำงานอยู่เบื้องหน้า แอปจะปรากฏในเครื่องมือจัดการงาน แต่จะไม่มีปุ่มหยุดข้างชื่อแอปให้ผู้ใช้แตะ

ใช้ API ที่สร้างขึ้นเพื่อวัตถุประสงค์เฉพาะแทนบริการที่ทำงานอยู่เบื้องหน้า

สําหรับ Use Case หลายรายการ มี API ของแพลตฟอร์มหรือ Jetpack ที่คุณสามารถใช้เพื่อทํางานต่างๆ ได้ ซึ่งปกติแล้วคุณอาจใช้บริการที่ทำงานอยู่เบื้องหน้า หากมี API ที่ออกแบบมาเป็นพิเศษซึ่งเหมาะสม คุณควรใช้ API ดังกล่าวแทนการใช้บริการที่ทำงานอยู่เบื้องหน้าเกือบทุกครั้ง API ที่สร้างขึ้นเพื่อวัตถุประสงค์หนึ่งๆ มักจะมีความสามารถเพิ่มเติมสำหรับ Use Case ที่เฉพาะเจาะจง ซึ่งคุณจะต้องสร้างขึ้นมาเอง ตัวอย่างเช่น Bubbles API จะจัดการตรรกะ UI ที่ซับซ้อนสําหรับแอปรับส่งข้อความที่ต้องติดตั้งใช้งานฟีเจอร์ฟองข้อความ

เอกสารประกอบสำหรับประเภทบริการที่ทำงานอยู่เบื้องหน้าจะแสดงทางเลือกที่ดีในการใช้แทนบริการที่ทำงานอยู่เบื้องหน้า

ข้อจำกัดในการเริ่มบริการที่ทำงานอยู่เบื้องหน้าจากเบื้องหลัง

แอปที่กําหนดเป้าหมายเป็น Android 12 ขึ้นไปจะไม่สามารถเริ่มบริการที่ทํางานอยู่เบื้องหน้าขณะที่แอปทํางานอยู่เบื้องหลัง ยกเว้นบางกรณีพิเศษ หากแอปพยายามเริ่มบริการที่ทำงานอยู่เบื้องหน้าขณะที่แอปทำงานอยู่เบื้องหลัง และบริการที่ทำงานอยู่เบื้องหน้าไม่ตรงกับกรณียกเว้นข้อใดข้อหนึ่ง ระบบจะแสดงForegroundServiceStartNotAllowedException

นอกจากนี้ หากแอปต้องการเปิดบริการที่ทำงานอยู่เบื้องหน้าซึ่งต้องใช้สิทธิ์ขณะใช้งาน (เช่น สิทธิ์เข้าถึงเซ็นเซอร์ร่างกาย กล้อง ไมโครโฟน หรือตำแหน่ง) แอปจะสร้างบริการดังกล่าวไม่ได้ขณะที่แอปทำงานอยู่เบื้องหลัง แม้ว่าแอปจะอยู่ในข้อยกเว้นข้อใดข้อหนึ่งจากข้อจำกัดการเริ่มทำงานในเบื้องหลังก็ตาม เหตุผลของข้อจำกัดนี้อธิบายอยู่ในส่วนข้อจำกัดในการเริ่มบริการที่ทำงานอยู่เบื้องหน้าซึ่งต้องใช้สิทธิ์ขณะใช้งาน

ข้อยกเว้นจากข้อจำกัดการเริ่มต้นทำงานในเบื้องหลัง

ในกรณีต่อไปนี้ แอปสามารถเริ่มบริการที่ทำงานอยู่เบื้องหน้าได้แม้ว่าแอปจะทำงานอยู่เบื้องหลังก็ตาม

ข้อจำกัดในการเริ่มบริการที่ทำงานอยู่เบื้องหน้าซึ่งต้องใช้สิทธิ์ขณะใช้งาน

ใน 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