พัฒนาประสบการณ์การนอนหลับด้วย Health Connect

หากต้องการสร้างประสบการณ์การติดตามการนอนหลับในแอป คุณสามารถใช้ Health Connect เพื่อทำสิ่งต่างๆ ได้ดังนี้

  • เขียนข้อมูลเซสชันการนอนหลับ
  • เขียนข้อมูลระยะการนอนหลับ
  • เขียนข้อมูลการนอนหลับ เช่น อัตราการเต้นของหัวใจ ความอิ่มตัวของออกซิเจน และอัตราการหายใจ
  • อ่านข้อมูลการนอนหลับจากแอปอื่นๆ

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

ภาพรวม: การสร้างเครื่องมือติดตามการนอนหลับที่ครอบคลุม

คุณสามารถสร้างประสบการณ์การติดตามการนอนหลับที่ครอบคลุมโดยใช้ Health Connect ได้ด้วยการทำตามขั้นตอนหลักๆ ต่อไปนี้

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

เวิร์กโฟลว์นี้ช่วยให้สามารถทำงานร่วมกับแอป Health Connect อื่นๆ ได้และยืนยันการเข้าถึงข้อมูลที่ผู้ใช้ควบคุม

ก่อนเริ่มต้น

สิ่งที่ควรทำก่อนติดตั้งใช้งานฟีเจอร์การนอนหลับ

หัวข้อสำคัญ

Health Connect แสดงข้อมูลการนอนหลับโดยใช้คอมโพเนนต์หลัก 2-3 รายการ SleepSessionRecord ทำหน้าที่เป็นบันทึกส่วนกลางสำหรับการนอนหลับ โดยมีรายละเอียดต่างๆ เช่น เวลาเริ่มต้นหรือสิ้นสุด และระยะการนอนหลับ ในระหว่างเซสชัน ระบบจะบันทึกประเภทข้อมูลต่างๆ เช่น HeartRateRecord หรือ OxygenSaturationRecord

เซสชันการนอนหลับ

ข้อมูลการนอนหลับแสดงโดย SleepSessionRecord โดยแต่ละระเบียนจะจัดเก็บข้อมูลต่อไปนี้

  • startTime
  • endTime
  • stages: รายการ SleepSessionRecord.Stage ซึ่งรวมถึงการหลับลึก หลับตื้น หลับฝัน (REM) และการตื่น
  • ข้อมูลเมตาของเซสชันที่ไม่บังคับ (ชื่อ บันทึก)

แอปอาจเขียนข้อมูลหลายประเภทที่เชื่อมโยงกับเซสชัน

ประเภทข้อมูล

ประเภทข้อมูลทั่วไปที่บันทึกระหว่างเซสชันการนอนหลับ ได้แก่

  • SleepSessionRecord: บันทึกระยะเวลาการนอนหลับและระยะการนอนหลับ ซึ่งรวมถึงการหลับลึก หลับตื้น หลับฝัน (REM) และการตื่น
  • HeartRateRecord: บันทึกอัตราการเต้นของหัวใจขณะนอนหลับ
  • OxygenSaturationRecord: บันทึกความอิ่มตัวของออกซิเจน (SpO2) ขณะนอนหลับ
  • RespiratoryRateRecord: บันทึกอัตราการหายใจขณะนอนหลับ

ระบบจะจัดเก็บข้อมูลแต่ละประเภทเป็นระเบียนแต่ละรายการ

ข้อควรพิจารณาในการพัฒนา

แอปติดตามการนอนหลับมักจะต้องทำงานเป็นระยะเวลานาน และทำงานในเบื้องหลังบ่อยครั้งเมื่อหน้าจอปิดอยู่ เมื่อสร้างฟีเจอร์การนอนหลับ สิ่งสำคัญคือต้องพิจารณาวิธีจัดการการดำเนินการในเบื้องหลังและขอสิทธิ์ที่จำเป็นสำหรับข้อมูลการนอนหลับ

การดำเนินการในเบื้องหลัง

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

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

รักษาความต่อเนื่องโดยใช้รหัสเซสชันที่สอดคล้องกันในการเขียนทั้งหมด

สิทธิ์

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

การเข้าถึงข้อมูลการนอนหลับได้รับการปกป้องโดยสิทธิ์ต่อไปนี้

  • android.permission.health.READ_SLEEP
  • android.permission.health.WRITE_SLEEP

หากต้องการเพิ่มความสามารถในการจัดการข้อมูลการนอนหลับลงในแอป ให้เริ่มต้นด้วยการขอสิทธิ์สำหรับประเภทข้อมูล SleepSession

นี่คือสิทธิ์ที่คุณต้องประกาศเพื่อให้สามารถเขียนข้อมูลการนอนหลับได้

<application>
  <uses-permission
android:name="android.permission.health.WRITE_SLEEP" />
...
</application>

หากต้องการอ่านข้อมูลการนอนหลับ คุณต้องขอสิทธิ์ต่อไปนี้

<application>
  <uses-permission
android:name="android.permission.health.READ_SLEEP" />
...
</application>

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

หลังจากสร้างอินสแตนซ์ไคลเอ็นต์แล้ว แอปของคุณต้องขอสิทธิ์จากผู้ใช้ ผู้ใช้ต้องได้รับอนุญาตให้ให้สิทธิ์หรือปฏิเสธสิทธิ์ได้ทุกเมื่อ

หากต้องการทำเช่นนั้น ให้สร้างชุดสิทธิ์สำหรับประเภทข้อมูลที่จำเป็น ตรวจสอบว่าได้ประกาศสิทธิ์ในชุดในไฟล์ Manifest ของ Android ก่อน

// Create a set of permissions for required data types
val PERMISSIONS =
    setOf(
  HealthPermission.getReadPermission(SleepSessionRecord::class),
  HealthPermission.getWritePermission(SleepSessionRecord::class),
  HealthPermission.getReadPermission(HeartRateRecord::class),
  HealthPermission.getWritePermission(HeartRateRecord::class),
  HealthPermission.getReadPermission(OxygenSaturationRecord::class),
  HealthPermission.getWritePermission(OxygenSaturationRecord::class),
  HealthPermission.getReadPermission(RespiratoryRateRecord::class),
  HealthPermission.getWritePermission(RespiratoryRateRecord::class)
)

ใช้ getGrantedPermissions เพื่อดูว่าแอปของคุณได้รับสิทธิ์ที่ จำเป็นแล้วหรือไม่ หากไม่ได้รับ ให้ใช้ createRequestPermissionResultContract เพื่อขอสิทธิ์เหล่านั้น ซึ่งจะแสดงหน้าจอขอสิทธิ์ของ Health Connect

// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()

val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
  if (granted.containsAll(PERMISSIONS)) {
    // Permissions successfully granted
  } else {
    // Lack of required permissions
  }
}

suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
  val granted = healthConnectClient.permissionController.getGrantedPermissions()
  if (granted.containsAll(PERMISSIONS)) {
    // Permissions already granted; proceed with inserting or reading data
  } else {
    requestPermissions.launch(PERMISSIONS)
  }
}

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

ติดตั้งใช้งานเซสชันการนอนหลับ

ส่วนนี้อธิบายเวิร์กโฟลว์ที่แนะนำสำหรับการบันทึกข้อมูลการนอนหลับ

หากต้องการจัดประเภทข้อมูล เช่น HeartRateRecord หรือ OxygenSaturationRecord ให้สอดคล้องกับเซสชันการนอนหลับ ให้บันทึกข้อมูลเหล่านั้นด้วยการประทับเวลาที่อยู่ในช่วง startTime และ endTime ของเซสชัน Health Connect ไม่ได้ใช้ตัวระบุเซสชันเพื่อลิงก์เซสชันการนอนหลับกับข้อมูลย่อยๆ แต่จะเชื่อมโยงกันโดยนัยผ่านช่วงเวลาที่ทับซ้อนกัน เมื่ออ่านข้อมูลการนอนหลับ คุณสามารถใช้ช่วงเวลาของเซสชัน เพื่อค้นหาประเภทข้อมูลที่เชื่อมโยงได้ ดังที่แสดงใน หัวข้อการอ่านข้อมูลการนอนหลับ

เขียนเซสชัน

แม้ว่าจะสามารถบันทึกข้อมูลย่อยๆ เช่น อัตราการเต้นของหัวใจได้ตลอดเซสชันการนอนหลับ แต่ต้องเขียน SleepSessionRecord ลงใน Health Connect เพียงครั้งเดียวเมื่อเซสชันเสร็จสิ้นแล้ว เช่น เมื่อผู้ใช้ตื่นขึ้น ระเบียนต้องมี เซสชัน startTime และ endTime รวมถึงรายการออบเจ็กต์ SleepSessionRecord.Stage ที่บันทึกระหว่างเซสชัน เนื่องจาก SleepSessionRecord กำหนดให้ endTime ต้องอยู่หลัง startTime

วิธีเขียนเซสชันการนอนหลับ

  1. สร้างรหัสระเบียนไคลเอ็นต์ที่ไม่ซ้ำกัน
  2. เมื่อผู้ใช้ตื่นขึ้นหรือหยุดการติดตามการนอนหลับ ให้รวบรวมระยะการนอนหลับทั้งหมดและสร้าง SleepSessionRecord
  3. แทรกระเบียนโดยใช้ insertRecords

ตัวอย่าง

val clientRecordId = UUID.randomUUID().toString()
val sessionStartTime = LocalDateTime.of(2023, 10, 30, 22, 0).toInstant(ZoneOffset.UTC)
val sessionEndTime = LocalDateTime.of(2023, 10, 31, 7, 0).toInstant(ZoneOffset.UTC)

val stages = mutableListOf<SleepSessionRecord.Stage>()
// Add recorded stages, for example:
stages.add(SleepSessionRecord.Stage(
    startTime = sessionStartTime.plusSeconds(3600),
    endTime = sessionStartTime.plusSeconds(7200),
    stage = SleepSessionRecord.STAGE_TYPE_LIGHT)
)
stages.add(SleepSessionRecord.Stage(
    startTime = sessionStartTime.plusSeconds(7200),
    endTime = sessionStartTime.plusSeconds(10800),
    stage = SleepSessionRecord.STAGE_TYPE_DEEP)
)
// ... other stages

val session = SleepSessionRecord(
    startTime = sessionStartTime,
    startZoneOffset = ZoneOffset.UTC,
    endTime = sessionEndTime,
    endZoneOffset = ZoneOffset.UTC,
    stages = stages,
    metadata = Metadata(clientRecordId = clientRecordId)
)

healthConnectClient.insertRecords(listOf(session))

การอ่านข้อมูลการนอนหลับ

แอปสามารถอ่านเซสชันการนอนหลับและข้อมูลที่เชื่อมโยงเพื่อสรุปกิจกรรม ให้ข้อมูลเชิงลึกด้านสุขภาพ หรือซิงค์ข้อมูลกับเซิร์ฟเวอร์ภายนอก ตัวอย่างเช่น คุณสามารถอ่าน SleepSessionRecord แล้วค้นหา HeartRateRecord ที่เกิดขึ้นในช่วงเวลาเดียวกัน

อ่านเซสชันพร้อมข้อมูลที่เชื่อมโยง

คุณสามารถอ่านเซสชันการนอนหลับโดยใช้ ReadRecordsRequest ที่มี SleepSessionRecord เป็นประเภทระเบียน โดยกรองตามช่วงเวลา หากต้องการอ่านข้อมูลที่เชื่อมโยงสำหรับเซสชันหนึ่งๆ ให้ส่งคำขอที่ 2 สำหรับประเภทข้อมูลที่เลือก เช่น HeartRateRecord โดยกรองตาม startTime และ endTime ของเซสชันการนอนหลับ

ตัวอย่างต่อไปนี้แสดงวิธีอ่านเซสชันการนอนหลับพร้อมข้อมูลอัตราการเต้นของหัวใจที่เชื่อมโยงสำหรับช่วงเวลาหนึ่งๆ

suspend fun readSleepSessionsWithAssociatedData(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response = healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = SleepSessionRecord::class,
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )
    )

    for (sleepRecord in response.records) {
        // Process each session
        val stages = sleepRecord.stages
        val notes = sleepRecord.notes

        // To read specific granular data (like heart rate) that occurred during
        // this session, use the session's startTime and endTime to filter
        // the request for that data type.
        val hrResponse = healthConnectClient.readRecords(
            ReadRecordsRequest(
                recordType = HeartRateRecord::class,
                timeRangeFilter = TimeRangeFilter.between(
                    sleepRecord.startTime,
                    sleepRecord.endTime
                )
            )
        )
        for (heartRateRecord in hrResponse.records) {
            for (sample in heartRateRecord.samples) {
                val bpm = sample.beatsPerMinute
            }
        }
    }
}

แนวทางปฏิบัติแนะนำ

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

  • ความถี่ในการเขียน
    • การติดตามที่ใช้งานอยู่(เบื้องหน้า): สำหรับการติดตามการนอนหลับที่ใช้งานอยู่ ให้เขียนข้อมูลเมื่อข้อมูลพร้อมใช้งานหรือเขียนข้อมูลทุกๆ 15 นาที
    • การซิงค์ในเบื้องหลัง: ใช้ WorkManager สำหรับการเขียนที่เลื่อนออกไป ตั้งเป้าหมายให้เขียนข้อมูลทุกๆ 15 นาทีเพื่อสร้างสมดุลระหว่างข้อมูลแบบเรียลไทม์กับประสิทธิภาพของแบตเตอรี่
    • การจัดกลุ่ม: อย่าเขียนเหตุการณ์เซ็นเซอร์แต่ละรายการแยกกัน แบ่งคำขอออกเป็นกลุ่มๆ Health Connect จัดการระเบียนได้สูงสุด 1,000 รายการต่อคำขอเขียน
  • รักษารหัสเซสชันให้คงที่และไม่ซ้ำกัน: ใช้ตัวระบุที่สอดคล้องกันสำหรับเซสชัน หากมีการแก้ไขหรืออัปเดตเซสชัน การใช้รหัสเดิมจะป้องกันไม่ให้ระบบถือว่าเซสชันนั้นเป็นเซสชันการนอนหลับใหม่ที่แยกต่างหาก
  • ใช้การจัดกลุ่มสำหรับประเภทข้อมูล: หากต้องการลดค่าใช้จ่ายในการป้อน/ส่งออกและประหยัดแบตเตอรี่ ให้จัดกลุ่มจุดข้อมูลเป็นการเรียก insertRecords ครั้งเดียวแทนที่จะเขียนแต่ละจุดแยกกัน
  • หลีกเลี่ยงการเขียนข้อมูลที่ซ้ำกัน: ใช้รหัสไคลเอ็นต์ เมื่อสร้างระเบียน ให้ตั้งค่า metadata.clientRecordId Health Connect ใช้รหัสนี้เพื่อระบุระเบียนที่ไม่ซ้ำกัน หากคุณพยายามเขียนระเบียนที่มี clientRecordId อยู่แล้ว Health Connect จะไม่สนใจรายการซ้ำหรืออัปเดตระเบียนที่มีอยู่แทนที่จะสร้างระเบียนใหม่ การตั้งค่า metadata.clientRecordId เป็นวิธีที่มีประสิทธิภาพที่สุดในการป้องกันรายการซ้ำระหว่างการลองซิงค์ใหม่หรือการติดตั้งแอปอีกครั้ง

    val record = RespiratoryRateRecord(
        rate = 16.0,
        time = time,
        zoneOffset = ZoneOffset.UTC,
        metadata = Metadata(
            // Use a unique ID from your own database
            clientRecordId = "respiratory_rate_20231030_1"
        )
    )
    
  • ตรวจสอบข้อมูลที่มีอยู่: ก่อนซิงค์ ให้ค้นหาช่วงเวลาเพื่อดูว่ามีระเบียนจากแอปของคุณอยู่แล้วหรือไม่

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

  • ระบุเหตุผลที่ชัดเจนในการขอสิทธิ์: ใช้โฟลว์ Permission.createIntent เพื่ออธิบายเหตุผลที่แอปของคุณต้องเข้าถึงข้อมูลสุขภาพ เช่น "เพื่อวิเคราะห์รูปแบบการนอนหลับของคุณ"

  • ทดสอบเซสชันที่ทำงานเป็นเวลานาน: ตรวจสอบการใช้แบตเตอรี่ระหว่างเซสชันที่ใช้เวลาหลายชั่วโมงเพื่อยืนยันว่าช่วงการจัดกลุ่มและการใช้เซ็นเซอร์ไม่ทำให้แบตเตอรี่ของอุปกรณ์หมดเร็ว

  • จัดเวลาประทับให้สอดคล้องกับอัตราเซ็นเซอร์: จับคู่เวลาประทับของระเบียนกับความถี่ที่แท้จริงของเซ็นเซอร์เพื่อรักษาความถูกต้องของข้อมูล

การทดสอบ

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

เครื่องมือยืนยัน

  • กล่องเครื่องมือ Health Connect: ใช้แอปคู่หูนี้เพื่อตรวจสอบ ระเบียนด้วยตนเอง ลบข้อมูลทดสอบ และจำลองการเปลี่ยนแปลงฐานข้อมูล ซึ่งเป็นวิธีที่ดีที่สุดในการยืนยันว่าระบบจัดเก็บระเบียนของคุณอย่างถูกต้อง
  • การทำ Unit Test ด้วย FakeHealthConnectClient: ใช้ไลบรารีการทดสอบ เพื่อยืนยันวิธีที่แอปจัดการกรณีขอบ เช่น การเพิกถอนสิทธิ์หรือข้อยกเว้นของ API โดยไม่ต้องใช้อุปกรณ์จริง

รายการตรวจสอบคุณภาพ

สถาปัตยกรรมทั่วไป

การติดตั้งใช้งานการติดตามการนอนหลับมักจะรวมถึงสิ่งต่อไปนี้

คอมโพเนนต์ จัดการ
ตัวควบคุมเซสชัน สถานะเซสชัน
ตัวจับเวลา
ตรรกะการจัดกลุ่ม
ตัวควบคุมประเภทข้อมูล
การเก็บรวบรวมข้อมูล
เลเยอร์ที่เก็บข้อมูล (ครอบคลุมการดำเนินการของ Health Connect) แทรกเซสชัน
แทรกประเภทข้อมูล
แทรกระยะการนอนหลับ
อ่านข้อมูลสรุปเซสชัน
เลเยอร์ UI (แสดง) ระยะเวลา
ประเภทข้อมูลแบบสด
ภาพระยะการนอนหลับ

การแก้ปัญหา

ลักษณะปัญหา สาเหตุที่เป็นไปได้ ความละเอียด
ไม่มีประเภทข้อมูล (เช่น อัตราการเต้นของหัวใจ) ไม่มีสิทธิ์เขียนหรือตัวกรองเวลาไม่ถูกต้อง ตรวจสอบว่าคุณได้ขอสิทธิ์ประเภทข้อมูลที่เฉพาะเจาะจงและผู้ใช้ได้ให้สิทธิ์แล้ว ตรวจสอบว่า ReadRecordsRequest ใช้ TimeRangeFilter ที่ตรงกับเซสชัน ดูหัวข้อสิทธิ์
เขียนเซสชันไม่สำเร็จ การประทับเวลาทับซ้อนกัน Health Connect อาจปฏิเสธระเบียนที่ทับซ้อนกับข้อมูลที่มีอยู่จากแอปเดียวกัน ตรวจสอบว่า startTime ของเซสชันใหม่อยู่หลัง endTime ของเซสชันก่อนหน้า
ไม่มีการบันทึกข้อมูลเซ็นเซอร์ระหว่างการนอนหลับ บริการที่ทำงานอยู่เบื้องหน้าถูกหยุดหรือไม่ได้ใช้งาน หากต้องการเก็บรวบรวมข้อมูลเซ็นเซอร์ตลอดทั้งคืนขณะที่หน้าจอปิดอยู่ คุณสามารถใช้ บริการที่ทำงานอยู่เบื้องหน้าที่มี foregroundServiceType="health"
ระเบียนซ้ำปรากฏขึ้น ไม่มี clientRecordId กำหนด clientRecordId ที่ไม่ซ้ำกันใน Metadata ของแต่ละระเบียน ซึ่งจะช่วยให้ Health Connect ขจัดข้อมูลซ้ำได้หากมีการเขียนข้อมูลเดียวกัน 2 ครั้งระหว่างการลองซิงค์ใหม่ ดูแนวทางปฏิบัติแนะนำ

ขั้นตอนการแก้ไขข้อบกพร่องทั่วไป

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