MediaSession — مفاهیم کلیدی، یکپارچه‌سازی و مکانیزم کار در اندروید

نویسنده: IT Sectr منتشر شده: 2026-05-23 زمان مطالعه: 8 دقیقه

MediaSession — مؤلفه چارچوب اندروید برای مدیریت پخش محتوای رسانه‌ای و یکپارچه‌سازی با دستگاه‌های خارجی است. این یک رابط واحد برای تعامل با هدست‌های بلوتوث، هدفون‌ها، Android Auto و مرکز رسانه سیستمی فراهم می‌کند. بر اساس Android Developers Guide, 2026، MediaSession جایگزین RemoteControlClient قدیمی شده و برای پخش‌کننده‌هایی که با سیستم همگام‌سازی می‌شوند الزامی است.

نکات اصلی

  • MediaSession — مؤلفه مرکزی برای مدیریت جریان‌های رسانه‌ای در اندروید است که دستورات را از منابع خارجی دریافت می‌کند.
  • از Bluetooth AVRCP، هدست‌ها، Android Auto، دستگاه‌های پوشیدنی و مرکز رسانه اندروید پشتیبانی می‌کند.
  • جلسه وضعیت پخش‌کننده (play/pause/next/previous) و فراداده‌ها (نام، اجراکننده، جلد) را با سیستم همگام‌سازی می‌کند.
  • برای کار به MediaSessionCompat از AndroidX نیاز دارد که سازگاری معکوس تا API 14 را فراهم می‌کند.
  • سیستم MediaSession.Callback دستورات ورودی را پردازش کرده و وضعیت MediaSession را تغییر می‌دهد.

MediaSession چیست؟

MediaSession — یک مؤلفه سیستمی اندروید است که به برنامه اجازه می‌دهد فعالیت رسانه‌ای خود را اعلام کرده و دستورات کنترلی از خارج دریافت کند. هنگامی که کاربر دکمه Play را روی هدست بلوتوث فشار می‌دهد، سیستم این رویداد را به MediaSession فعال منتقل می‌کند و برنامه از طریق Callback خود واکنش نشان می‌دهد.

قبل از اندروید 5.0 برای این اهداف از RemoteControlClient استفاده می‌شد، اما انعطاف‌پذیری لازم را نداشت و سناریوهای مدرن — Android Auto، ساعت‌های هوشمند، بلندگوهای هوشمند را پشتیبانی نمی‌کرد. MediaSession در API 21 معرفی شد و به استاندارد دوفاکتو برای همه برنامه‌های اندروید با پخش صوتی و تصویری تبدیل شد.

بر اساس Android Developer Documentation (2026)، برنامه باید برای هر منبع پخش مستقل یک MediaSession ایجاد کند. در هر لحظه فقط یک جلسه فعال می‌تواند وجود داشته باشد — هر جلسه جدید به طور خودکار جلسه قبلی را غیرفعال می‌کند.

MediaSession و MediaBrowserService

ترکیب MediaSession با MediaBrowserService چرخه کامل مدیریت رسانه را فراهم می‌کند: سرویس درخت محتوا (لیست‌های پخش، کاتالوگ‌ها) را ارائه می‌دهد و جلسه دستورات ناوبری و پخش را دریافت می‌کند. این معماری توصیه‌شده توسط Google برای پخش‌کننده‌های موسیقی، پادکست‌ها و کتاب‌های صوتی است.

MediaBrowserService به عنوان یک foreground-service با اعلان راه‌اندازی می‌شود که عملکرد برنامه را حتی پس از کشته شدن Activity تضمین می‌کند. این برای پخش‌کننده‌های صوتی که باید در هنگام کوچک‌سازی برنامه به پخش ادامه دهند حیاتی است.

MediaSession چگونه کار می‌کند

جلسه دو نوع تعامل را پشتیبانی می‌کند: دستورات را از MediaController (سمت مشتری) دریافت می‌کند و وضعیت را از طریق PlaybackState پخش می‌کند. MediaController می‌تواند در همان فرآیند یا در یک برنامه جداگانه باشد — سیستم درخواست‌ها را از طریق SessionToken مسیریابی می‌کند.

هنگامی که کاربر دستیار صوتی اندروید را فراخوانی کرده و می‌گوید «آهنگ بعدی را پخش کن»، سیستم MediaSession فعال را از طریق ارتباط با MediaBrowserService پیدا کرده و دستور ACTION_SKIP_TO_NEXT را ارسال می‌کند. Callback برنامه فراخوانی onSkipToNext() را دریافت کرده و PlaybackState را به‌روزرسانی می‌کند.

به‌روزرسانی PlaybackState از طریق setPlaybackState() بلافاصله همه MediaControllerهای متصل را مطلع می‌کند. مرکز رسانه سیستمی، دستگاه بلوتوث و Android Auto همزمان به‌روزرسانی را دریافت می‌کنند — تأخیر در شرایط عادی از 50 میلی‌ثانیه تجاوز نمی‌کند.

PlaybackState و فراداده‌های آن

PlaybackState شامل پرچم‌های وضعیت کلیدی است: isPlaying، موقعیت، سرعت، اقدامات موجود (play، pause، seek، stop). بدون PlaybackState پر شده صحیح، سیستم نمی‌داند برنامه چه دستوراتی را پشتیبانی می‌کند و رویدادهای مربوطه را ارسال نمی‌کند.

فراداده‌ها (MediaMetadata) وضعیت را با اطلاعات مربوط به آهنگ فعلی تکمیل می‌کنند — title, artist, album art URI. Android Auto و دستگاه‌های پوشیدنی از MediaMetadata برای نمایش اطلاعات روی صفحه استفاده می‌کنند. طبق Google I/O 2024، پر کردن صحیح MediaMetadata دید برنامه را در لانچرهای شخص ثالث 40٪ افزایش می‌دهد.

مؤلفه‌های کلیدی MediaSession

معماری MediaSession از چهار مؤلفه به هم مرتبط تشکیل شده است که هر کدام وظیفه خود را حل می‌کنند. توسعه‌دهنده باید هر چهار مورد را برای یکپارچه‌سازی کامل با سیستم پیاده‌سازی کند.

  • MediaSessionCompat — کلاس اصلی جلسه، با تگ برنامه ایجاد می‌شود و PendingIntent را برای دکمه‌های رسانه دریافت می‌کند.
  • MediaSession.Callback — پردازشگر دستورات. onPlay، onPause، onSkipToNext، onSeekTo و سایر متدها را پیاده‌سازی می‌کند.
  • PlaybackStateCompat — وضعیت فعلی پخش‌کننده. شامل پرچم‌ها، موقعیت، سرعت و لیست اقدامات موجود است.
  • MediaMetadataCompat — فراداده‌های رسانه فعلی: نام، اجراکننده، آلبوم، جلد، مدت زمان.

چرخه حیات MediaSession

جلسه در onCreate سرویس یا Activity با فراخوانی MediaSessionCompat(context, tag) ایجاد می‌شود. پس از ایجاد حتماً باید setFlags(FLAG_HANDLES_MEDIA_BUTTONS | FLAG_HANDLES_TRANSPORT_CONTROLS) فراخوانی شود. در onDestroy برای آزادسازی منابع سیستم، release() فراخوانی می‌شود.

مدیریت نادرست چرخه حیات یکی از اشتباهات رایج است. اگر release() فراخوانی نشود، جلسه در سیستم باقی می‌ماند و برنامه بعدی ممکن است وضعیت نادرستی دریافت کند. اندروید 13+ در هنگام نشت جلسه در Logcat اخطار نشان می‌دهد.

یکپارچه‌سازی MediaSession در برنامه

یکپارچه‌سازی پایه با ایجاد جلسه و پیاده‌سازی Callback آغاز می‌شود. توصیه می‌شود از MediaSessionCompat از کتابخانه AndroidX media استفاده کنید که API یکپارچه‌ای برای تمام نسخه‌های اندروید — از API 14 تا 35 — فراهم می‌کند.

ایجاد MediaSession و 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()
    }
}

در مثال، MediaSession با تگ MusicService و پرچم‌هایی برای پردازش دکمه‌های رسانه ایجاد می‌شود. Callback متدهای onPlay و onPause را پیاده‌سازی کرده و PlaybackState را به‌روزرسانی می‌کند. متد setActions اقدامات موجود را که سیستم روی صفحه قفل و در مرکز رسانه نمایش می‌دهد اعلام می‌کند.

تنظیم 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)
}

فراداده‌ها باید در هر تغییر آهنگ به‌روزرسانی شوند. سیستم از METADATA_KEY_TITLE و METADATA_KEY_ARTIST برای نمایش اطلاعات روی نمایشگرهای بلوتوث خودروها و دستگاه‌های پوشیدنی استفاده می‌کند. اگر URI جلد تنظیم نشود، پخش‌کننده یک placeholder خاکستری نشان می‌دهد.

پردازش دستورات رسانه‌ای از بلوتوث و هدفون

هدست‌های بلوتوث دستورات را از طریق پروفایل AVRCP 1.6+ ارسال می‌کنند. اندروید این دستورات را به intentهای ACTION_MEDIA_BUTTON منتقل می‌کند که توسط MediaSession با پرچم FLAG_HANDLES_MEDIA_BUTTONS گرفته می‌شوند.

هنگامی که کاربر دکمه Play را روی هدفون بلوتوث فشار می‌دهد، سیستم یک KeyEvent با کد KEYCODE_MEDIA_PLAY ایجاد می‌کند که به متد onMediaButtonEvent Callback ارسال می‌شود. اگر در Callback متد onPlay() پیاده‌سازی شده باشد، سیستم مستقیماً آن را فراخوانی می‌کند. با فشار تکی دکمه روی هدست، KEYCODE_MEDIA_PLAY_PAUSE ارسال می‌شود — پخش‌کننده باید وضعیت را تغییر دهد.

پردازش سناریوهای پیچیده با چند دکمه

هدفون‌های بلوتوث مدرن می‌توانند تا 5 دکمه داشته باشند: صدا +/-، play/pause، next، previous. هر دکمه KeyEvent مخصوص خود را تولید می‌کند که باید به درستی توسط Callback پردازش شود. فشار دوبل play/pause معمولاً در بسیاری از هدفون‌ها به عنوان رفتن به آهنگ بعدی (ACTION_SKIP_TO_NEXT) تفسیر می‌شود.

بر اساس Android Compatibility Definition Document (2026)، تمام برنامه‌های دارای محتوای رسانه‌ای موظف به پردازش صحیح KEYCODE_MEDIA_PLAY_PAUSE هستند. نادیده گرفتن این الزام منجر به کاهش خودکار رتبه برنامه در Google Play برای دسته Musiqi & Audio می‌شود.

همگام‌سازی با مرکز رسانه سیستمی

از اندروید 11 به بعد، مرکز رسانه سیستمی (Media Control Panel) تا 5 جلسه MediaSession اخیر را در پنل اعلان‌ها نمایش می‌دهد. کاربر می‌تواند بدون باز کردن برنامه، پخش‌کننده را کنترل کند. برای نمایش صحیح باید MediaBrowserService پیاده‌سازی شده و PlaybackState به درستی پر شود.

Media Control Panel نمایش می‌دهد: نام آهنگ، اجراکننده، جلد (از MediaMetadata)، دکمه‌های کنترل (از اقدامات مجاز PlaybackState). اگر برنامه PlaybackState را حداقل هر 10 ثانیه یک بار در هنگام پخش فعال به‌روزرسانی نکند، مرکز رسانه جلسه را از پنل مخفی می‌کند.

Foreground-service با اعلان

kotlin
private fun startForegroundService() {
    val notification = NotificationCompat.Builder(this, "media_channel")
        .setSmallIcon(R.drawable.ic_play)
        .setContentTitle("در حال پخش")
        .setContentText(currentTrackTitle)
        .setPriority(NotificationCompat.PRIORITY_LOW)
        .setStyle(
            androidx.media.app.NotificationCompat.MediaStyle()
                .setMediaSession(mediaSession.sessionToken)
        )
        .build()
    startForeground(1001, notification)
}

اعلان MediaStyle از طریق sessionToken با MediaSession مرتبط می‌شود و دکمه‌های استاندارد رسانه را نمایش می‌دهد. بدون MediaStyle، اعلان مانند یک اخطار معمولی بدون دکمه‌های کنترل به نظر می‌رسد. اندروید 13+ برای نمایش نیاز به مجوز صریح POST_NOTIFICATIONS دارد.

سوالات متداول

آیا برنامه می‌تواند چندین MediaSession فعال همزمان داشته باشد؟

از نظر فنی بله، اما در یک لحظه فقط یک جلسه فعال محسوب می‌شود. هنگام ایجاد جلسه جدید بدون فراخوانی setActive(true)، جلسه قبلی فعال باقی می‌ماند. توصیه می‌شود به ازای هر برنامه یا هر منبع صوتی مستقل یک جلسه با تغییر وضعیت فعال داشته باشید.

MediaSession چگونه با Audio Focus تعامل می‌کند؟

MediaSession به طور خودکار Audio Focus را مدیریت نمی‌کند — این یک مکانیزم جداگانه است. هنگام دریافت دستور onPlay، توسعه‌دهنده شخصاً از طریق AudioManager درخواست AudioFocus می‌کند و هنگام از دست دادن فوکوس، پخش را از طریق جلسه متوقف می‌کند.

چرا دکمه‌های رسانه روی هدفون با برنامه من کار نمی‌کنند؟

تنظیم پرچم‌های FLAG_HANDLES_MEDIA_BUTTONS و FLAG_HANDLES_TRANSPORT_CONTROLS را بررسی کنید. همچنین مطمئن شوید جلسه فعال است (setActive(true)). در اندروید 12+ دکمه‌های رسانه فقط از طریق MediaSession کار می‌کنند — registerMediaButtonEventReceiver قدیمی پشتیبانی نمی‌شود.

آیا MediaBrowserService برای کار MediaSession ضروری است؟

برای پردازش پایه دکمه‌ها — خیر. اما برای یکپارچه‌سازی با Android Auto، Wear OS و مرکز رسانه سیستمی، MediaBrowserService مورد نیاز است. Google پیاده‌سازی MediaBrowserService را در همه برنامه‌های با پخش طولانی مدت صوتی توصیه می‌کند.

چگونه بررسی کنیم که MediaSession به درستی پیکربندی شده است؟

از دستور adb shell dumpsys media_session برای مشاهده جلسات فعال، Callback و PlaybackState آنها استفاده کنید. این ابزار همه جلسات ثبت‌شده را با تگ، فعالیت و آخرین وضعیت شناخته شده نشان می‌دهد — ابزاری مناسب برای اشکال‌زدایی.

خلاصه

  • MediaSession — روش استاندارد مدیریت پخش در اندروید، جایگزین RemoteControlClient از API 21.
  • جلسه دستورات را از Bluetooth، هدفون‌ها، Android Auto و مرکز رسانه سیستمی از طریق سیستم Callback دریافت می‌کند.
  • PlaybackState و MediaMetadata — دو مؤلفه اجباری برای همگام‌سازی صحیح با رابط کاربری سیستم.
  • یکپارچه‌سازی از طریق MediaSessionCompat از AndroidX media انجام می‌شود که سازگاری با API 14+ را فراهم می‌کند.
  • برای نمایش در مرکز رسانه سیستمی به MediaBrowserService و foreground-service با اعلان MediaStyle نیاز است.
  • مدیریت Audio Focus — یک وظیفه جداگانه است که توسط MediaSession خودکار نمی‌شود. توسعه‌دهنده فوکوس را شخصاً مدیریت می‌کند.
  • برای اشکال‌زدایی از adb shell dumpsys media_session برای مشاهده جلسات فعال و وضعیت آنها استفاده کنید.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید