การใช้งานเซสชันสื่อ

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

เซสชันสื่อจะอยู่ข้างๆ โปรแกรมเล่นสื่อที่ตนเองจัดการ คุณควรสร้าง และเริ่มต้นเซสชันสื่อด้วยเมธอด onCreate() ของกิจกรรมหรือ ที่เป็นเจ้าของเซสชันสื่อและโปรแกรมเล่นที่เกี่ยวข้อง

เริ่มต้นเซสชันสื่อ

เซสชันสื่อที่สร้างใหม่ไม่มีความสามารถใดๆ คุณต้องเริ่มต้นเซสชันโดยทำตามขั้นตอนต่อไปนี้

  • ตั้งค่าการแฟล็กเพื่อให้เซสชันสื่อได้รับ Callback จากตัวควบคุมสื่อและปุ่มสื่อ
  • สร้างและเริ่มต้นอินสแตนซ์ของ PlaybackStateCompat และมอบหมายให้กับเซสชัน สถานะการเล่นจะเปลี่ยนแปลงไปตลอดเซสชัน เราจึงแนะนำให้แคช PlaybackStateCompat.Builder ไว้ใช้ซ้ำ
  • สร้างอินสแตนซ์ของ MediaSessionCompat.Callback และมอบหมายให้กับเซสชัน (ดูข้อมูลเพิ่มเติมเกี่ยวกับ Callback ด้านล่าง)

คุณควรสร้างและเริ่มต้นเซสชันสื่อในเมธอด onCreate() ของเมธอด กิจกรรม หรือบริการที่เป็นเจ้าของเซสชัน

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

คงสถานะการเล่นและข้อมูลเมตาไว้

มี 2 คลาสที่แสดงถึงสถานะของเซสชันสื่อ

PlaybackStateCompat จะอธิบายสถานะการทำงานในปัจจุบันของโปรแกรมเล่น ฟีเจอร์เหล่านั้นรวมถึง

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

MediaMetadataCompat จะอธิบายถึงเนื้อหาที่กำลังเล่น:

  • ชื่อศิลปิน อัลบั้ม และแทร็ก
  • ระยะเวลาการติดตาม
  • ภาพปกอัลบั้มที่จะแสดงในหน้าจอล็อก รูปภาพเป็นบิตแมปที่มีขนาดสูงสุด 320x320dp (หากใหญ่กว่า จะลดขนาดลง)
  • อินสแตนซ์ของ ContentUris ที่ชี้ไปยังอาร์ตเวิร์กเวอร์ชันที่ใหญ่กว่า

สถานะโปรแกรมเล่นและข้อมูลเมตาอาจเปลี่ยนแปลงได้ตลอดอายุเซสชันสื่อ ทุกครั้งที่สถานะหรือข้อมูลเมตาเปลี่ยนแปลง คุณต้องใช้เครื่องมือสร้างที่สอดคล้องกันสำหรับแต่ละคลาส PlaybackStateCompat.Builder() หรือ MediaMetadataCompat.Builder() แล้วส่งอินสแตนซ์ใหม่ไปยังเซสชันสื่อด้วยการเรียกใช้ setPlaybackState() หรือ setMetaData() หากต้องการลดการใช้หน่วยความจำโดยรวมจากการดำเนินการที่พบบ่อยเหล่านี้ เป็นความคิดที่ดีที่จะสร้างเครื่องมือสร้างเพียงครั้งเดียวและนำมาใช้ซ้ำได้ตลอดอายุเซสชัน

สถานะและข้อผิดพลาด

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

เมื่อใดก็ตามที่การเล่นถูกขัดจังหวะ คุณควรแสดงข้อผิดพลาดที่ร้ายแรง: ตั้งค่า สถานะการส่งไปยัง STATE_ERROR และระบุข้อผิดพลาดที่เกี่ยวข้องกับ setErrorMessage(int, CharSequence) ตราบใดที่ข้อผิดพลาดถูกบล็อกการเล่น PlaybackState จะดำเนินการต่อ เพื่อรายงาน STATE_ERROR และข้อผิดพลาด

ข้อผิดพลาดที่ไม่ร้ายแรงเกิดขึ้นเมื่อแอปของคุณจัดการคำขอไม่ได้ แต่ยังเล่นต่อไปได้ การขนย้ายยังคงอยู่ใน "ปกติ" (เช่น STATE_PLAYING) แต่ PlaybackState มีรหัสข้อผิดพลาด ตัวอย่างเช่น หากเพลงสุดท้ายกำลังเล่นอยู่และผู้ใช้ขอข้ามไปยังเพลงถัดไป จะเล่นต่อได้ แต่คุณควรสร้าง PlaybackState ใหม่ที่มีรหัสข้อผิดพลาด ERROR_CODE_END_OF_QUEUE และ จากนั้นโทร setPlaybackState() ตัวควบคุมสื่อที่แนบอยู่กับเซสชันจะได้รับการ Callback onPlaybackStateChanged() และอธิบายสิ่งที่เกิดขึ้นให้ผู้ใช้ทราบ ควรรายงานข้อผิดพลาดที่ไม่ร้ายแรงเพียงครั้งเดียว ณ เวลาที่เกิดขึ้น เมื่อเซสชันอัปเดต PlaybackState ครั้งถัดไป ระบบจะไม่ตั้งค่าข้อผิดพลาดที่ไม่ร้ายแรงเดียวกันนี้อีก (เว้นแต่จะเกิดข้อผิดพลาดตามคําขอใหม่)

หน้าจอล็อกเซสชันสื่อ

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

ภาพปกอัลบั้ม

ใน Android 4.0 (API ระดับ 14) ถึง Android 10 (API ระดับ 29) พื้นหลัง ของหน้าจอล็อกจะแสดงปกอัลบั้มของคุณ เฉพาะเมื่อเซสชันสื่อ ข้อมูลเมตาจะมีบิตแมปเบื้องหลัง

ตัวควบคุมการรับส่งข้อมูล

ใน Android 4.0 (API ระดับ 14) ถึง Android 4.4 (API ระดับ 19) เมื่อมีเซสชันสื่ออยู่และข้อมูลเมตาของเซสชันสื่อจะมีบิตแมปเบื้องหลังที่หน้าจอล็อกจะแสดงตัวควบคุมการส่งโดยอัตโนมัติ

ใน Android 5.0 (API ระดับ 21) ขึ้นไป ระบบจะไม่ให้การรับส่งข้อมูล บนหน้าจอล็อก คุณควรใช้ไอคอน MediaStyle แทน การแจ้งเตือน เพื่อแสดงตัวควบคุมการรับส่งข้อมูล

เพิ่มการกระทำที่กำหนดเอง

แอปพลิเคชันสื่อสามารถกำหนดการดำเนินการที่กำหนดเองได้ ตัวอย่างเช่น ยกนิ้วโป้ง ชอบ หรือ กรอกลับ 30 วินาที การดําเนินการที่กําหนดเองควรใช้ลักษณะการทํางานใหม่ทั้งหมด ควรทำ ไม่ใช้การดําเนินการที่กําหนดเองเพื่อแทนที่การดําเนินการควบคุมการส่งมาตรฐานรายการใดรายการหนึ่ง กำหนดไว้ใน PlayStateCompat

เพิ่มการกระทำที่กำหนดเองด้วย addCustomAction() ตัวอย่างต่อไปนี้แสดงวิธีเพิ่มการควบคุมสำหรับการกดสุดยอด

Kotlin

stateBuilder.addCustomAction(
        PlaybackStateCompat.CustomAction.Builder(
                CUSTOM_ACTION_THUMBS_UP,
                resources.getString(R.string.thumbs_up),
                thumbsUpIcon
        ).run {
            setExtras(customActionExtras)
            build()
        }
)

Java

stateBuilder.addCustomAction(new PlaybackStateCompat.CustomAction.Builder(
    CUSTOM_ACTION_THUMBS_UP, resources.getString(R.string.thumbs_up), thumbsUpIcon)
    .setExtras(customActionExtras)
    .build());

ดูตัวอย่างที่สมบูรณ์ใน Universal Music Player

คุณตอบกลับการดำเนินการด้วย onCustomAction()

Kotlin

override fun onCustomAction(action: String, extras: Bundle?) {
    when(action) {
        CUSTOM_ACTION_THUMBS_UP -> {
            ...
        }
    }
}

Java

@Override
public void onCustomAction(@NonNull String action, Bundle extras) {
    if (CUSTOM_ACTION_THUMBS_UP.equals(action)) {
        ...
    }
}

โปรดดูโปรแกรมเล่นเพลงสากลด้วย

Callback ของเซสชันสื่อ

เมธอด Callback ของเซสชันสื่อหลักคือ onPlay(), onPause() และ onStop() ซึ่งเป็นที่สำหรับเพิ่มโค้ดที่ใช้ควบคุมโปรแกรมเล่นของคุณ

เนื่องจากคุณสร้างอินสแตนซ์และกำหนด Callback ของเซสชันที่รันไทม์ (ใน onCreate()) แอปของคุณจึงสามารถกำหนด Callback สำรองที่ใช้โปรแกรมเล่นที่ต่างกัน และเลือกชุดค่าผสม Callback/โปรแกรมเล่นที่เหมาะสมได้โดยขึ้นอยู่กับระดับอุปกรณ์และ/หรือระบบ คุณเปลี่ยนโปรแกรมเล่นได้โดยไม่ต้องเปลี่ยนส่วนที่เหลือของแอป เช่น คุณสามารถใช้ ExoPlayer เมื่อทำงานใน Android 4.1 (API ระดับ 16) ขึ้นไป และใช้ MediaPlayer ในระบบก่อนหน้านี้

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

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