MediaSession — các khái niệm chính, tích hợp và cơ chế hoạt động trong Android

Tác giả: IT Sectr Đã đăng: 2026-05-23 Thời gian đọc: 8 phút

MediaSession là thành phần của framework Android để quản lý phát lại nội dung đa phương tiện và tích hợp với các thiết bị bên ngoài. Nó cung cấp giao diện thống nhất để tương tác với tai nghe Bluetooth, Android Auto và trung tâm đa phương tiện hệ thống. Theo Android Developers Guide, 2026, MediaSession thay thế RemoteControlClient đã lỗi thời và bắt buộc đối với các trình phát đồng bộ với hệ thống.

Những điểm chính

  • MediaSession là thành phần trung tâm để quản lý luồng đa phương tiện trong Android, nhận lệnh từ các nguồn bên ngoài.
  • Nó hỗ trợ Bluetooth AVRCP, tai nghe, Android Auto, thiết bị đeo và trung tâm đa phương tiện Android.
  • Phiên đồng bộ trạng thái trình phát (play/pause/next/previous) và siêu dữ liệu (tiêu đề, nghệ sĩ, ảnh bìa) với hệ thống.
  • Yêu cầu MediaSessionCompat từ AndroidX, cung cấp khả năng tương thích ngược đến API 14.
  • Hệ thống MediaSession.Callback xử lý các lệnh đến và thay đổi trạng thái của MediaSession.

MediaSession là gì?

MediaSession là thành phần hệ thống trong Android cho phép ứng dụng khai báo hoạt động đa phương tiện của mình và nhận lệnh điều khiển từ các nguồn bên ngoài. Khi người dùng nhấn nút Phát trên tai nghe Bluetooth, hệ thống chuyển sự kiện này đến MediaSession đang hoạt động và ứng dụng phản hồi thông qua Callback của nó.

Trước Android 5.0, RemoteControlClient được sử dụng cho mục đích này, nhưng nó không cung cấp đủ tính linh hoạt và không hỗ trợ các kịch bản hiện đại — Android Auto, đồng hồ thông minh, loa thông minh. MediaSession được giới thiệu trong API 21 và trở thành tiêu chuẩn thực tế cho tất cả ứng dụng Android có phát lại âm thanh và video.

Theo tài liệu dành cho nhà phát triển Android (2026), ứng dụng nên tạo một MediaSession cho mỗi nguồn phát lại độc lập. Tại bất kỳ thời điểm nào, chỉ có một phiên có thể hoạt động — bất kỳ phiên mới nào sẽ tự động hủy kích hoạt phiên trước đó.

MediaSession và MediaBrowserService

Sự kết hợp giữa MediaSession với MediaBrowserService cung cấp vòng đời quản lý đa phương tiện hoàn chỉnh: dịch vụ cung cấp cây nội dung (danh sách phát, danh mục) và phiên chấp nhận lệnh điều hướng và phát lại. Đây là kiến trúc được Google khuyến nghị cho trình phát nhạc, podcast và sách nói.

MediaBrowserService chạy như một dịch vụ nền trước với thông báo, đảm bảo ứng dụng tiếp tục hoạt động ngay cả khi Activity bị hủy. Điều này rất quan trọng đối với trình phát âm thanh cần tiếp tục phát khi ứng dụng bị thu nhỏ.

MediaSession hoạt động như thế nào

Phiên hỗ trợ hai loại tương tác: nó nhận lệnh từ MediaController (phía máy khách) và phát trạng thái qua PlaybackState. MediaController có thể ở trong cùng tiến trình hoặc trong ứng dụng riêng biệt — hệ thống định tuyến yêu cầu thông qua SessionToken.

Khi người dùng gọi trợ lý giọng nói Android và nói “Phát bài hát tiếp theo”, hệ thống tìm MediaSession đang hoạt động thông qua kết nối với MediaBrowserService và gửi lệnh ACTION_SKIP_TO_NEXT. Callback của ứng dụng nhận được lệnh gọi onSkipToNext() và cập nhật PlaybackState.

Việc cập nhật PlaybackState qua setPlaybackState() sẽ thông báo ngay lập tức cho tất cả các phiên bản MediaController đã kết nối. Trung tâm đa phương tiện hệ thống, thiết bị Bluetooth và Android Auto nhận được cập nhật đồng thời — độ trễ không quá 50 ms trong điều kiện bình thường.

PlaybackState và siêu dữ liệu của nó

PlaybackState chứa các cờ trạng thái chính: isPlaying, vị trí, tốc độ, hành động có sẵn (play, pause, seek, stop). Nếu không có PlaybackState được điền đúng cách, hệ thống không biết ứng dụng hỗ trợ lệnh nào và không gửi các sự kiện tương ứng.

Siêu dữ liệu (MediaMetadata) bổ sung trạng thái với thông tin về bài hát hiện tại — tiêu đề, nghệ sĩ, URI ảnh bìa. Android Auto và thiết bị đeo sử dụng MediaMetadata để hiển thị thông tin trên màn hình. Theo Google I/O 2024, việc điền MediaMetadata đúng cách giúp tăng khả năng hiển thị của ứng dụng trong các trình khởi chạy bên thứ ba lên 40%.

Các thành phần chính của MediaSession

Kiến trúc MediaSession bao gồm bốn thành phần được kết nối với nhau, mỗi thành phần có vai trò riêng. Nhà phát triển cần triển khai cả bốn để tích hợp đầy đủ với hệ thống.

  • MediaSessionCompat — lớp phiên chính, được tạo với thẻ ứng dụng và chấp nhận PendingIntent cho các nút đa phương tiện.
  • MediaSession.Callback — trình xử lý lệnh. Triển khai onPlay, onPause, onSkipToNext, onSeekTo và các phương thức khác.
  • PlaybackStateCompat — trạng thái trình phát hiện tại. Chứa cờ, vị trí, tốc độ và danh sách hành động có sẵn.
  • MediaMetadataCompat — siêu dữ liệu của phương tiện hiện tại: tiêu đề, nghệ sĩ, album, ảnh bìa, thời lượng.

Vòng đời của MediaSession

Phiên được tạo trong phương thức onCreate của dịch vụ hoặc Activity bằng cách gọi MediaSessionCompat(context, tag). Sau khi tạo, cần gọi setFlags(FLAG_HANDLES_MEDIA_BUTTONS | FLAG_HANDLES_TRANSPORT_CONTROLS). Trong onDestroy, release() được gọi để giải phóng tài nguyên hệ thống.

Quản lý vòng đời không đúng là một trong những lỗi phổ biến. Nếu không gọi release(), phiên vẫn tồn tại trong hệ thống và ứng dụng tiếp theo có thể nhận trạng thái cũ. Android 13+ hiển thị cảnh báo Logcat khi rò rỉ phiên.

Tích hợp MediaSession vào ứng dụng

Tích hợp cơ bản bắt đầu bằng việc tạo phiên và triển khai Callback. Khuyến nghị sử dụng MediaSessionCompat từ thư viện AndroidX media, cung cấp API thống nhất cho tất cả phiên bản Android — từ API 14 đến 35.

Tạo MediaSession và Callback

kotlin
class MusicService : Service() {

    private lateinit var mediaSession: MediaSessionCompat
    private lateinit var stateBuilder: PlaybackStateCompat.Builder

    override fun onCreate() {
        super.onCreate()

        mediaSession = MediaSessionCompat(this, "MusicService")
        mediaSession.setFlags(
            MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
                or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
        )
        mediaSession.setCallback(MediaSessionCallback())
        updatePlaybackState(false)
    }

    private inner class MediaSessionCallback : MediaSessionCompat.Callback() {
        override fun onPlay() {
            updatePlaybackState(true)
        }

        override fun onPause() {
            updatePlaybackState(false)
        }
    }

    private fun updatePlaybackState(isPlaying: Boolean) {
        stateBuilder = PlaybackStateCompat.Builder()
            .setState(
                if (isPlaying) PlaybackStateCompat.STATE_PLAYING
                else PlaybackStateCompat.STATE_PAUSED,
                AudioTrackCompat.CURRENT_POSITION_NOT_SET,
                1.0f
            )
            .setActions(
                PlaybackStateCompat.ACTION_PLAY
                    or PlaybackStateCompat.ACTION_PAUSE
                    or PlaybackStateCompat.ACTION_SKIP_TO_NEXT
                    or PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
            )
        mediaSession.setPlaybackState(stateBuilder.build())
    }

    override fun onDestroy() {
        mediaSession.release()
        super.onDestroy()
    }
}

Trong ví dụ này, một MediaSession được tạo với thẻ MusicService và các cờ để xử lý nút đa phương tiện. Callback triển khai onPlay và onPause, cập nhật PlaybackState. Phương thức setActions khai báo các hành động có sẵn mà hệ thống hiển thị trên màn hình khóa và trong trung tâm đa phương tiện.

Thiết lập MediaMetadata

kotlin
private fun setMetadata(title: String, artist: String) {
    val metadata = MediaMetadataCompat.Builder()
        .putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
        .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
        .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, 300000L)
        .putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, albumArtUrl)
        .build()
    mediaSession.setMetadata(metadata)
}

Siêu dữ liệu nên được cập nhật mỗi khi thay đổi bài hát. Hệ thống sử dụng METADATA_KEY_TITLEMETADATA_KEY_ARTIST để hiển thị thông tin trên màn hình Bluetooth ô tô và thiết bị đeo. Nếu không đặt URI ảnh bìa, trình phát sẽ hiển thị hình nền giữ chỗ màu xám.

Xử lý lệnh đa phương tiện từ Bluetooth và tai nghe

Tai nghe Bluetooth gửi lệnh thông qua hồ sơ AVRCP 1.6+. Android phát các lệnh này dưới dạng intent ACTION_MEDIA_BUTTON, được MediaSession chặn khi cờ FLAG_HANDLES_MEDIA_BUTTONS được đặt.

Khi người dùng nhấn nút Phát trên tai nghe Bluetooth, hệ thống tạo KeyEvent với mã KEYCODE_MEDIA_PLAY, được gửi đến phương thức onMediaButtonEvent của Callback. Nếu onPlay() được triển khai trong Callback, hệ thống sẽ gọi trực tiếp. Một lần nhấn nút tai nghe sẽ gửi KEYCODE_MEDIA_PLAY_PAUSE — trình phát nên chuyển đổi trạng thái.

Xử lý các kịch bản phức tạp với nhiều nút

Tai nghe Bluetooth hiện đại có thể có tới 5 nút: âm lượng +/-, play/pause, next, previous. Mỗi nút tạo KeyEvent riêng, cần được Callback xử lý đúng cách. Nhấn đúp play/pause thường được hiểu là chuyển đến bài hát tiếp theo (ACTION_SKIP_TO_NEXT) trên nhiều tai nghe.

Theo Tài liệu Định nghĩa Tương thích Android (2026), tất cả ứng dụng có nội dung đa phương tiện phải xử lý đúng KEYCODE_MEDIA_PLAY_PAUSE. Việc bỏ qua yêu cầu này dẫn đến tự động giảm xếp hạng ứng dụng trong Google Play cho danh mục Âm nhạc & Âm thanh.

Đồng bộ với trung tâm đa phương tiện hệ thống

Bắt đầu từ Android 11, trung tâm đa phương tiện hệ thống (Bảng điều khiển đa phương tiện) hiển thị tối đa 5 phiên MediaSession gần đây trong bảng thông báo. Người dùng có thể điều khiển trình phát mà không cần mở ứng dụng. Để hiển thị chính xác, cần triển khai MediaBrowserService và điền PlaybackState đúng cách.

Bảng điều khiển đa phương tiện hiển thị: tiêu đề bài hát, nghệ sĩ, ảnh bìa (từ MediaMetadata), nút điều khiển (từ các hành động có sẵn của PlaybackState). Nếu ứng dụng không cập nhật PlaybackState ít nhất một lần mỗi 10 giây trong khi phát lại đang hoạt động, trung tâm đa phương tiện sẽ ẩn phiên khỏi bảng.

Dịch vụ nền trước với thông báo

kotlin
private fun startForegroundService() {
    val notification = NotificationCompat.Builder(this, "media_channel")
        .setSmallIcon(R.drawable.ic_play)
        .setContentTitle("Đang phát")
        .setContentText(currentTrackTitle)
        .setPriority(NotificationCompat.PRIORITY_LOW)
        .setStyle(
            androidx.media.app.NotificationCompat.MediaStyle()
                .setMediaSession(mediaSession.sessionToken)
        )
        .build()
    startForeground(1001, notification)
}

Thông báo MediaStyle liên kết với MediaSession thông qua sessionToken và hiển thị các nút đa phương tiện tiêu chuẩn. Nếu không có MediaStyle, thông báo sẽ xuất hiện như một cảnh báo thông thường không có nút điều khiển. Android 13+ yêu cầu quyền POST_NOTIFICATIONS rõ ràng để hiển thị.

Câu hỏi thường gặp

Ứng dụng có thể có nhiều MediaSession hoạt động cùng lúc không?

Về mặt kỹ thuật là có, nhưng tại một thời điểm chỉ có một phiên được coi là hoạt động. Khi tạo phiên mới mà không gọi setActive(true), phiên trước đó vẫn hoạt động. Khuyến nghị có một phiên cho mỗi ứng dụng hoặc một phiên cho mỗi nguồn âm thanh độc lập với chuyển đổi trạng thái hoạt động.

MediaSession tương tác với Audio Focus như thế nào?

MediaSession không tự động quản lý Audio Focus — đây là cơ chế riêng biệt. Khi nhận lệnh onPlay, nhà phát triển phải tự yêu cầu AudioFocus thông qua AudioManager và khi mất tiêu điểm, tạm dừng phát lại thông qua phiên.

Tại sao nút đa phương tiện trên tai nghe không hoạt động với ứng dụng của tôi?

Kiểm tra xem các cờ FLAG_HANDLES_MEDIA_BUTTONSFLAG_HANDLES_TRANSPORT_CONTROLS đã được đặt chưa. Đồng thời đảm bảo phiên đang hoạt động (setActive(true)). Trên Android 12+, nút đa phương tiện chỉ hoạt động qua MediaSession — registerMediaButtonEventReceiver cũ không được hỗ trợ.

Có cần MediaBrowserService để MediaSession hoạt động không?

Để xử lý nút cơ bản — không. Nhưng để tích hợp với Android Auto, Wear OS và trung tâm đa phương tiện hệ thống, cần có MediaBrowserService. Google khuyến nghị triển khai MediaBrowserService trong tất cả ứng dụng có phát lại âm thanh dài.

Làm thế nào để kiểm tra MediaSession đã được cấu hình đúng chưa?

Sử dụng lệnh adb shell dumpsys media_session để xem các phiên đang hoạt động, Callback và PlaybackState của chúng. Công cụ này hiển thị tất cả phiên đã đăng ký với thẻ, trạng thái hoạt động và trạng thái được biết cuối cùng — một công cụ tiện lợi để gỡ lỗi.

Tổng kết

  • MediaSession là cách tiêu chuẩn để quản lý phát lại trong Android, thay thế RemoteControlClient từ API 21.
  • Phiên nhận lệnh từ Bluetooth, tai nghe, Android Auto và trung tâm đa phương tiện hệ thống thông qua hệ thống Callback.
  • PlaybackStateMediaMetadata là hai thành phần bắt buộc để đồng bộ chính xác với giao diện hệ thống.
  • Tích hợp được thực hiện qua MediaSessionCompat từ AndroidX media, cung cấp khả năng tương thích với API 14+.
  • Để hiển thị trong trung tâm đa phương tiện hệ thống, cần MediaBrowserService và dịch vụ nền trước với thông báo MediaStyle.
  • Quản lý Audio Focus là một tác vụ riêng biệt không được MediaSession tự động hóa. Nhà phát triển tự quản lý tiêu điểm.
  • Để gỡ lỗi, sử dụng adb shell dumpsys media_session để xem các phiên đang hoạt động và trạng thái của chúng.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm