Zygote
Builder trackintermediate

I05 — Foreground music service

Build a media playback service with a notification, a media session and a foreground service type. Learn why the notification is mandatory, what the type buys you, and when the system will stop the service.

3 minAPI 26–37 · 17verified 2026-10-27

A foreground service is the platform's answer to "this must keep running". It comes with a notification the user cannot dismiss while the service is foreground, a declared type, and a set of restrictions that are easy to discover only by hitting them.

What you are building#

A service that plays a looping audio file, shows a media notification, and exposes play/pause through a MediaSession. It declares a foreground service type, starts from a user action, and shuts down cleanly when playback stops.

Steps#

  1. Add a notification channel

    Create a channel at app startup with a name, a description and an importance. On Android 8.0 and later, a notification without a channel is not shown.1

    You should seeThe channel exists before the notification.
  2. Declare the service and its type

    Add the service with android:foregroundServiceType="mediaPlayback" and the matching permission. Since Android 14, a foreground service must declare a type, and the type must match what it does.

    You should seeThe manifest lists the type.
  3. The service entry point:

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val notification = buildNotification()
        startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)
        return START_NOT_STICKY
    }
  4. Build the notification

    Use a media style notification with a MediaSession. The notification is the user's control surface and the platform's evidence that the service is visible.

    You should seeA notification with a play/pause action.
  5. Start the service from a user action

    Start it in response to a button press, not from a background receiver. Background starts are restricted, and a user action is the cleanest way to satisfy the restriction.2

    You should seeThe service starts and the notification appears.
  6. Call startForeground

    Call startForeground with the notification within the allowed window. A service that starts but never calls it is killed.

    You should seeThe notification is posted and the service is foreground.
  7. Play audio

    Use MediaPlayer or Media3's ExoPlayer for the loop. The point is the service lifetime, not the decoder; either works.

    You should seeAudio plays and continues when the app is backgrounded.
  8. Stop cleanly

    On pause or stop, stop the foreground state and stop the service. A service that stays foreground without doing work is a battery complaint and a policy violation.

    You should seeThe notification disappears.
  9. Hit the limit deliberately

    Try starting the service from a background context and observe the restriction. Then try a type that does not match the work and observe the platform's response. These failures are the actual lesson.

    You should seeAn exception or a stopped service.
Inspect the service
adb shell dumpsys activity services com.example.musicservice
adb shell dumpsys notification | grep -i -A 5 com.example.musicservice
adb shell am start-foreground-service -n com.example.musicservice/.PlaybackService
Example output
Illustrative output — package and service names differ.

Verification#

Background the app and confirm the audio continues and the notification stays. Then force-stop the app and confirm both stop. The difference is the point: a foreground service survives backgrounding and does not survive a force-stop.

What you learned#

  • The notification is the contract. A foreground service is visible by design, and the notification is how the user knows.
  • The type is mandatory and semantic. It is not a label; it constrains what the service may do and for how long.
  • Background starts are restricted. The supported path is a user action, or a documented exemption.
  • Stopping is part of the design. A service that never stops is a bug even when it works.

Read Foreground services for when a foreground service is the right tool, and Notifications for the channel model.

Extend it#

  1. Add a media session callback so hardware media keys control playback.
  2. Add a second type for a download that happens alongside playback, and observe the type combination rules.
  3. Replace the player with Media3 and compare the session and notification plumbing.

Sources#

Sources

Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.

  1. docsNotifications overviewdeveloper.android.comaccessed 2026-10-27↩
  2. docsForeground services overview | Background workdeveloper.android.comaccessed 2026-10-27↩
  3. docsMedia3 overviewdeveloper.android.comaccessed 2026-10-27↩
  4. docsBehavior changes: Apps targeting Android 13 or higherdeveloper.android.comaccessed 2026-10-27↩
  5. docsסקירה כללית על תכונות וממשקי APIdeveloper.android.comaccessed 2026-10-27↩
  6. docsBackground tasks overview | Background workdeveloper.android.comaccessed 2026-10-27↩