Medyayı arka planda oynatın

Uygulamanız ekranda olmasa bile (ör. kullanıcı diğer uygulamalarla etkileşimde bulunurken) medyayı arka planda oynatabilirsiniz.

Bunu yapmak için MediaPlayer'ı bir MediaBrowserServiceCompat hizmetine yerleştirir ve başka bir etkinlikteki MediaBrowserCompat ile etkileşimde bulunmasını sağlarsınız.

Bu istemci ve sunucu kurulumunu uygularken dikkatli olun. Arka plan hizmetinde çalışan bir oynatıcının sistemin geri kalanıyla nasıl etkileşim kuracağıyla ilgili beklentiler vardır. Uygulamanız bu beklentileri karşılamazsa kullanıcı kötü bir deneyim yaşayabilir. Ayrıntılar için Ses Uygulaması Oluşturma başlıklı makaleyi inceleyin.

Bu sayfada, bir hizmetin içinde uyguladığınızda MediaPlayer'ı yönetmeyle ilgili özel talimatlar açıklanmaktadır.

Eşzamansız olarak çalıştırma

Activity gibi, Service içindeki tüm çalışmalar varsayılan olarak tek bir ileti dizisinde yapılır. Hatta aynı uygulamadan bir etkinlik ve hizmet çalıştırdığınızda bunlar varsayılan olarak aynı iş parçacığını ("ana iş parçacığı") kullanır.

Hizmetler, gelen amaçları hızlı bir şekilde işlemeli ve bunlara yanıt verirken asla uzun hesaplamalar yapmamalıdır. Yoğun iş yükü veya engelleme çağrılarını eşzamansız olarak gerçekleştirmeniz gerekir. Bunu, kendinizin uyguladığı başka bir iş parçacığından veya çerçevedeki eşzamansız işleme için sunulan birçok olanaktan yararlanarak yapabilirsiniz.

Örneğin, ana iş parçacığınızda MediaPlayer kullanırken şunları yapmalısınız:

Örneğin:

Kotlin

private const val ACTION_PLAY: String = "com.example.action.PLAY"

class MyService: Service(), MediaPlayer.OnPreparedListener {

    private var mMediaPlayer: MediaPlayer? = null

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        ...
        val action: String = intent.action
        when(action) {
            ACTION_PLAY -> {
                mMediaPlayer = ... // initialize it here
                mMediaPlayer?.apply {
                    setOnPreparedListener(this@MyService)
                    prepareAsync() // prepare async to not block main thread
                }

            }
        }
        ...
    }

    /** Called when MediaPlayer is ready */
    override fun onPrepared(mediaPlayer: MediaPlayer) {
        mediaPlayer.start()
    }
}

Java

public class MyService extends Service implements MediaPlayer.OnPreparedListener {
    private static final String ACTION_PLAY = "com.example.action.PLAY";
    MediaPlayer mediaPlayer = null;

    public int onStartCommand(Intent intent, int flags, int startId) {
        ...
        if (intent.getAction().equals(ACTION_PLAY)) {
            mediaPlayer = ... // initialize it here
            mediaPlayer.setOnPreparedListener(this);
            mediaPlayer.prepareAsync(); // prepare async to not block main thread
        }
    }

    /** Called when MediaPlayer is ready */
    public void onPrepared(MediaPlayer player) {
        player.start();
    }
}

Eşzamansız hataları işleme

Eşzamanlı işlemlerde hatalar bir istisna veya hata koduyla bildirilir. Ancak eşzamansız kaynakları kullandığınızda uygulamanızı hatalar konusunda uygun şekilde bilgilendirmeniz gerekir. MediaPlayer durumunda, MediaPlayer.OnErrorListener özelliğini uygular ve MediaPlayer örneğinizde ayarlarsınız:

Kotlin

class MyService : Service(), MediaPlayer.OnErrorListener {

    private var mediaPlayer: MediaPlayer? = null

    fun initMediaPlayer() {
        // ...initialize the MediaPlayer here...
        mediaPlayer?.setOnErrorListener(this)
    }

    override fun onError(mp: MediaPlayer, what: Int, extra: Int): Boolean {
        // ... react appropriately ...
        // The MediaPlayer has moved to the Error state, must be reset!
    }
}

Java

public class MyService extends Service implements MediaPlayer.OnErrorListener {
    MediaPlayer mediaPlayer;

    public void initMediaPlayer() {
        // ...initialize the MediaPlayer here...
        mediaPlayer.setOnErrorListener(this);
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        // ... react appropriately ...
        // The MediaPlayer has moved to the Error state, must be reset!
    }
}

Bir hata oluştuğunda MediaPlayer, Hata durumuna geçer. Tekrar kullanabilmek için sıfırlamanız gerekir. Ayrıntılar için MediaPlayer sınıfının tam durum şemasına bakın.

Uyanık kalma kilitlerini kullanma

Arka planda müzik çalarken veya aktarırken sistemin oynatmanıza müdahale etmesini (ör. cihazın uyku moduna geçmesini) önlemek için uyanık kalma kilitlerini kullanmanız gerekir.

Uyanık kalma kilidi, uygulamanızın telefon boşta kaldığında bile kullanılabilir olması gereken özellikleri kullandığına dair sisteme gönderilen bir sinyaldir.

MediaPlayer oynatılırken CPU'nun çalışmaya devam etmesini sağlamak için MediaPlayer öğenizi başlatırken setWakeMode() yöntemini çağırın. MediaPlayer, oynatma sırasında belirtilen kilidi tutar, duraklatıldığında veya durdurulduğunda ise kilidi serbest bırakır:

Kotlin

mediaPlayer = MediaPlayer().apply {
    // ... other initialization here ...
    setWakeMode(applicationContext, PowerManager.PARTIAL_WAKE_LOCK)
}

Java

mediaPlayer = new MediaPlayer();
// ... other initialization here ...
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);

Ancak bu örnekte edinilen uyanık kalma kilidi yalnızca CPU'nun uyanık kalmasını sağlar. Ağ üzerinden medya yayını yapıyorsanız ve kablosuz ağ kullanıyorsanız muhtemelen bir WifiLock da tutmak istersiniz. Bu tutma işlemini manuel olarak yapmanız ve bırakmanız gerekir. Bu nedenle, uzak URL ile MediaPlayer hazırlamaya başladığınızda Wi-Fi kilidini oluşturup edinmeniz gerekir.

Örneğin:

Kotlin

val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiLock: WifiManager.WifiLock =
    wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock")

wifiLock.acquire()

Java

WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
    .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");

wifiLock.acquire();

Medya içeriğinizi duraklattığınızda veya durdurduğunuzda ya da artık ağa ihtiyacınız kalmadığında kilidi serbest bırakmanız gerekir:

Kotlin

wifiLock.release()

Java

wifiLock.release();

Temizleme işlemi gerçekleştirme

Daha önce de belirtildiği gibi, MediaPlayer nesnesi önemli miktarda sistem kaynağı tüketebilir. Bu nedenle, yalnızca ihtiyacınız olduğu sürece saklamalı ve işiniz bittiğinde release() işlevini çağırmalısınız. Çöp toplayıcı yalnızca bellek ihtiyaçlarına duyarlı olduğundan ve diğer medya ile ilgili kaynakların eksikliğine duyarlı olmadığından, MediaPlayer geri alması biraz zaman alabilir. Bu nedenle, bu temizleme yöntemini sistem çöp toplama işlemine güvenmek yerine açıkça çağırmak önemlidir. Bu nedenle, bir hizmet kullandığınızda onDestroy() yöntemini her zaman geçersiz kılmanız gerekir. Böylece MediaPlayer'ı yayınladığınızdan emin olursunuz:

Kotlin

class MyService : Service() {

    private var mediaPlayer: MediaPlayer? = null
    // ...

    override fun onDestroy() {
        super.onDestroy()
        mediaPlayer?.release()
    }
}

Java

public class MyService extends Service {
   MediaPlayer mediaPlayer;
   // ...

   @Override
   public void onDestroy() {
       super.onDestroy();
       if (mediaPlayer != null) mediaPlayer.release();
   }
}

MediaPlayer cihazınızı kapatılırken serbest bırakmanın yanı sıra, serbest bırakmak için her zaman başka fırsatlar da aramalısınız. Örneğin, uzun bir süre boyunca medya oynatamayacağınızı düşünüyorsanız (ör. ses odağını kaybettikten sonra) mevcut MediaPlayer öğenizi kesinlikle serbest bırakmalı ve daha sonra tekrar oluşturmalısınız. Öte yandan, oynatmayı yalnızca çok kısa bir süre durdurmayı planlıyorsanız MediaPlayer oluşturup tekrar hazırlamanın getireceği ek yükten kaçınmak için bu öğeyi saklamanız önerilir.

Daha fazla bilgi

Jetpack Media3, uygulamanızda medya oynatma için önerilen çözümdür. Daha fazla bilgi edinin.

Bu sayfalarda ses ve video kaydetme, depolama ve oynatma ile ilgili konular ele alınır: