MediaRouter'a genel bakış

Uygulamanızda MediaRouter çerçevesini kullanmak için MediaRouter nesnesinin bir örneğini almanız ve yönlendirme etkinliklerini dinlemek üzere bir MediaRouter.Callback nesnesi eklemeniz gerekir. Bir medya rotası üzerinden gönderilen içerik, rotanın ilişkili MediaRouteProvider cihazından geçer (Bluetooth çıkış cihazı gibi birkaç özel durum hariç). Şekil 1'de, cihazlar arasında içerik yönlendirmek için kullanılan sınıfların üst düzey görünümü sağlanmaktadır.

Şekil 1. Uygulamaların kullandığı önemli medya yönlendiricisi sınıflarına genel bakış.

Not: Uygulamanızın Google Cast cihazlarını desteklemesini istiyorsanız Cast SDK'sını kullanmanız ve uygulamanızı Cast göndereni olarak oluşturmanız gerekir. Doğrudan MediaRouter çerçevesini kullanmak yerine Cast dokümanlarındaki talimatları uygulayın.

Medya yönlendirme düğmesi

Android uygulamaları, medya yönlendirmesini kontrol etmek için medya yönlendirme düğmesi kullanmalıdır. MediaRouter çerçevesi, düğme için standart bir arayüz sağlar. Bu arayüz, kullanıcıların mümkün olduğunda yönlendirmeyi tanımasına ve kullanmasına yardımcı olur. Medya yönlendirme düğmesi genellikle Şekil 2'de gösterildiği gibi uygulamanızın işlem çubuğunun sağ tarafına yerleştirilir.

2. Şekil. Medya yönlendirme düğmesini seçin.

Kullanıcı medya yönlendirme düğmesine bastığında, kullanılabilir medya yolları Şekil 3'te gösterildiği gibi bir listede görünür.

3. Şekil. Medya yönlendirme düğmesine basıldıktan sonra gösterilen kullanılabilir medya rotalarının listesi.

Medya yönlendirme düğmesi oluşturmak için şu adımları uygulayın:

  1. AppCompatActivity kullanma
  2. Medya yönlendirme düğmesi menü öğesini tanımlayın
  3. MediaRouteSelector oluşturma
  4. İşlem çubuğuna medya yönlendirme düğmesi ekleme
  5. Etkinliğinizin yaşam döngüsünde MediaRouter.Callback yöntemlerini oluşturun ve yönetin

Bu bölümde ilk dört adım açıklanmaktadır. Sonraki bölümde Geri çağırma yöntemleri açıklanmaktadır.

AppCompatActivity kullanma

Bir etkinlikte medya yönlendiricisi çerçevesini kullandığınızda etkinliği AppCompatActivity içinden genişletmeniz ve androidx.appcompat.app paketini içe aktarmanız gerekir. Uygulama geliştirme projenize androidx.appcompat:appcompat ve androidx.mediarouter:mediarouter destek kitaplıklarını eklemeniz gerekir. Projenize destek kitaplıkları ekleme hakkında daha fazla bilgi edinmek için Android Jetpack'i kullanmaya başlama bölümüne bakın.

Dikkat: Medya yönlendiricisi çerçevesinin androidx uygulamasını kullandığınızdan emin olun. Eski android.media paketini kullanmayın.

Medya yönlendirme düğmesi için bir menü öğesi tanımlayan bir xml dosyası oluşturun. Öğenin işlemi MediaRouteActionProvider sınıfı olmalıdır. Örnek bir dosya:

// myMediaRouteButtonMenuItem.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      >

    <item android:id="@+id/media_route_menu_item"
        android:title="@string/media_route_menu_title"
        app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
        app:showAsAction="always"
    />
</menu>

MediaRouteSelector oluşturma

Medya yönlendirme düğmesi menüsünde görünen rotalar bir MediaRouteSelector ile belirlenir. Etkinliğinizi AppCompatActivity öğesinden genişletin ve aşağıdaki kod örneğinde gösterildiği gibi onCreate() yönteminden MediaRouteSelector.Builder çağrısı yapan etkinlik oluşturulduğunda seçiciyi oluşturun. Seçicinin bir sınıf değişkenine kaydedildiğini ve izin verilen rota türlerinin MediaControlIntent nesneleri eklenerek belirtildiğini unutmayın:

Kotlin

class MediaRouterPlaybackActivity : AppCompatActivity() {

    private var mSelector: MediaRouteSelector? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Create a route selector for the type of routes your app supports.
        mSelector = MediaRouteSelector.Builder()
                // These are the framework-supported intents
                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
                .build()
    }
}

Java

public class MediaRouterPlaybackActivity extends AppCompatActivity {
    private MediaRouteSelector mSelector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create a route selector for the type of routes your app supports.
        mSelector = new MediaRouteSelector.Builder()
                // These are the framework-supported intents
                .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
                .build();
    }
}

Çoğu uygulama için gereken tek rota türü CATEGORY_REMOTE_PLAYBACK'dir. Bu rota türü, uygulamanızı çalıştıran cihazı uzaktan kumanda olarak ele alır. Bağlı alıcı cihaz tüm içerik verisi alma, kod çözme ve oynatma işlemlerini gerçekleştirir. Google Cast'i destekleyen uygulamalar (ör. Chromecast) bu şekilde çalışır.

Bazı üreticiler "ikincil çıkış" olarak adlandırılan özel bir yönlendirme seçeneğini desteklemektedir. Bu yönlendirmeyle medya uygulamanız, video veya müzikleri doğrudan seçili uzak alıcı cihazdaki ekrana ve/veya hoparlörlere alır, oluşturur ve aktarır. Kablosuz özellikli müzik sistemlerine veya video ekranlarına içerik göndermek için ikincil çıkışı kullanın. Bu cihazların bulunmasını ve seçilmesini etkinleştirmek için MediaRouteSelector'a CATEGORY_LIVE_AUDIO veya CATEGORY_LIVE_VIDEO kontrol kategorilerini eklemeniz gerekir. Kendi Presentation iletişim kutunuzu da oluşturup işlemeniz gerekir.

İşlem çubuğuna medya yönlendirme düğmesi ekleme

Medya yönlendirme menüsü ve MediaRouteSelector tanımlandıktan sonra, bir etkinliğe medya yönlendirme düğmesi ekleyebilirsiniz. Seçenekler menüsü eklemek için her etkinliğinizde onCreateOptionsMenu() yöntemini geçersiz kılın.

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    super.onCreateOptionsMenu(menu)

    // Inflate the menu and configure the media router action provider.
    menuInflater.inflate(R.menu.sample_media_router_menu, menu)

    // Attach the MediaRouteSelector to the menu item
    val mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item)
    val mediaRouteActionProvider =
            MenuItemCompat.getActionProvider(mediaRouteMenuItem) as MediaRouteActionProvider

    // Attach the MediaRouteSelector that you built in onCreate()
    selector?.also(mediaRouteActionProvider::setRouteSelector)

    // Return true to show the menu.
    return true
}

Java

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    // Inflate the menu and configure the media router action provider.
    getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);

    // Attach the MediaRouteSelector to the menu item
    MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
    MediaRouteActionProvider mediaRouteActionProvider =
            (MediaRouteActionProvider)MenuItemCompat.getActionProvider(
            mediaRouteMenuItem);
    // Attach the MediaRouteSelector that you built in onCreate()
    mediaRouteActionProvider.setRouteSelector(selector);

    // Return true to show the menu.
    return true;
}

İşlem çubuğunu uygulamanızda uygulama hakkında daha fazla bilgi için İşlem Çubuğu geliştirici kılavuzuna bakın.

Ayrıca, herhangi bir görünümde MediaRouteButton olarak da medya yönlendirme düğmesi ekleyebilirsiniz. setRouteSelector() yöntemini kullanarak düğmeye bir MediaRouteSelector eklemeniz gerekir. Medya yönlendirme düğmesinin uygulamanıza entegre edilmesiyle ilgili yönergeler için Google Cast Tasarım Kontrol Listesi'ne bakın.

MediaRouter geri çağırmaları

Aynı cihazda çalışan tüm uygulamalar tek bir MediaRouter örneğini ve rotalarını paylaşır (uygulamanın MediaRouteSelector tarafından her uygulama için filtrelenir). Her bir etkinlik, kendi MediaRouter.Callback yöntemlerini kullanarak MediaRouter ile iletişim kurar. Kullanıcı bir yol seçtiğinde, değiştirdiğinde veya bağlantısını kestiğinde MediaRouter geri çağırma yöntemlerini çağırır.

Geri çağırma işleminde, yönlendirme etkinlikleri hakkında bilgi almak için geçersiz kılabileceğiniz birkaç yöntem vardır. En azından, MediaRouter.Callback sınıfı uygulamanız onRouteSelected() ve onRouteUnselected() öğelerini geçersiz kılmalıdır.

MediaRouter paylaşılan bir kaynak olduğundan uygulamanızın, olağan etkinlik yaşam döngüsü geri çağırmalarına yanıt olarak MediaRouter geri çağırmalarını yönetmesi gerekir:

  • Etkinlik oluşturulduğunda (onCreate(Bundle)) MediaRouter işaretçisini tutup uygulamanın kullanım ömrü boyunca tutun.
  • Etkinlik görünür hale geldiğinde MediaRouter'a geri çağırmalar ekleyin (onStart()) ve gizlendiğinde bunları ayırın (onStop()).

Aşağıdaki kod örneğinde, geri çağırma nesnesinin nasıl oluşturulup kaydedileceği, MediaRouter örneğinin nasıl alınacağı ve geri çağırmaların nasıl yönetileceği gösterilmektedir. onStart() içinde geri çağırmaları eklerken CALLBACK_FLAG_REQUEST_DISCOVERY işaretinin kullanıldığına dikkat edin. Bu işlem, MediaRouteSelector'ınızın medya yönlendirme düğmesinin kullanılabilir rota listesini yenilemesine olanak tanır.

Kotlin

class MediaRouterPlaybackActivity : AppCompatActivity() {

    private var mediaRouter: MediaRouter? = null
    private var mSelector: MediaRouteSelector? = null

    // Variables to hold the currently selected route and its playback client
    private var mRoute: MediaRouter.RouteInfo? = null
    private var remotePlaybackClient: RemotePlaybackClient? = null

    // Define the Callback object and its methods, save the object in a class variable
    private val mediaRouterCallback = object : MediaRouter.Callback() {

        override fun onRouteSelected(router: MediaRouter, route: MediaRouter.RouteInfo) {
            Log.d(TAG, "onRouteSelected: route=$route")
            if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
                // Stop local playback (if necessary)
                // ...

                // Save the new route
                mRoute = route

                // Attach a new playback client
                remotePlaybackClient =
                    RemotePlaybackClient(this@MediaRouterPlaybackActivity, mRoute)

                // Start remote playback (if necessary)
                // ...
            }
        }

        override fun onRouteUnselected(
                router: MediaRouter,
                route: MediaRouter.RouteInfo,
                reason: Int
        ) {
            Log.d(TAG, "onRouteUnselected: route=$route")
            if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {

                // Changed route: tear down previous client
                mRoute?.also {
                    remotePlaybackClient?.release()
                    remotePlaybackClient = null
                }

                // Save the new route
                mRoute = route

                when (reason) {
                    MediaRouter.UNSELECT_REASON_ROUTE_CHANGED -> {
                        // Resume local playback (if necessary)
                        // ...
                    }
                }
            }
        }
    }


    // Retain a pointer to the MediaRouter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Get the media router service.
        mediaRouter = MediaRouter.getInstance(this)
        ...
    }

    // Use this callback to run your MediaRouteSelector to generate the
    // list of available media routes
    override fun onStart() {
        mSelector?.also { selector ->
            mediaRouter?.addCallback(selector, mediaRouterCallback,
                    MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY)
        }
        super.onStart()
    }

    // Remove the selector on stop to tell the media router that it no longer
    // needs to discover routes for your app.
    override fun onStop() {
        mediaRouter?.removeCallback(mediaRouterCallback)
        super.onStop()
    }
    ...
}

Java

public class MediaRouterPlaybackActivity extends AppCompatActivity {
    private MediaRouter mediaRouter;
    private MediaRouteSelector mSelector;

    // Variables to hold the currently selected route and its playback client
    private MediaRouter.RouteInfo mRoute;
    private RemotePlaybackClient remotePlaybackClient;

    // Define the Callback object and its methods, save the object in a class variable
    private final MediaRouter.Callback mediaRouterCallback =
            new MediaRouter.Callback() {

        @Override
        public void onRouteSelected(MediaRouter router, RouteInfo route) {
            Log.d(TAG, "onRouteSelected: route=" + route);

            if (route.supportsControlCategory(
                MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){
                // Stop local playback (if necessary)
                // ...

                // Save the new route
                mRoute = route;

                // Attach a new playback client
                remotePlaybackClient = new RemotePlaybackClient(this, mRoute);

                // Start remote playback (if necessary)
                // ...
            }
        }

        @Override
        public void onRouteUnselected(MediaRouter router, RouteInfo route, int reason) {
            Log.d(TAG, "onRouteUnselected: route=" + route);

            if (route.supportsControlCategory(
                MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){

                // Changed route: tear down previous client
                if (mRoute != null && remotePlaybackClient != null) {
                    remotePlaybackClient.release();
                    remotePlaybackClient = null;
                }

                // Save the new route
                mRoute = route;

                if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) {
                    // Resume local playback  (if necessary)
                    // ...
                }
            }
        }
    }


    // Retain a pointer to the MediaRouter
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get the media router service.
        mediaRouter = MediaRouter.getInstance(this);
        ...
    }

    // Use this callback to run your MediaRouteSelector to generate the list of available media routes
    @Override
    public void onStart() {
        mediaRouter.addCallback(mSelector, mediaRouterCallback,
                MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
        super.onStart();
    }

    // Remove the selector on stop to tell the media router that it no longer
    // needs to discover routes for your app.
    @Override
    public void onStop() {
        mediaRouter.removeCallback(mediaRouterCallback);
        super.onStop();
    }
    ...
}

Medya yönlendiricisi çerçevesi de bir etkinlik için geri çağırmanın eklenmesi ve kaldırılmasıyla ilgili MediaRouteDiscoveryFragment sınıfı sağlar.

Not: Müzik çalma uygulaması yazıyorsanız ve uygulamanın arka planda müzik çalmasını istiyorsanız oynatma için Service oluşturmanız ve hizmetin yaşam döngüsü geri çağırmalarından medya yönlendirici çerçevesini çağırmanız gerekir.

Uzaktan oynatma rotasını kontrol etme

Uzaktan oynatma rotası seçtiğinizde uygulamanız uzaktan kumanda işlevi görür. Rotanın diğer ucundaki cihaz tüm içerik verisi alma, kod çözme ve oynatma işlevlerini yerine getirir. Uygulamanızın kullanıcı arayüzündeki kontroller RemotePlaybackClient nesnesi kullanarak alıcı cihazla iletişim kurar.

RemotePlaybackClient sınıfı, içerik oynatmayı yönetmek için ek yöntemler sunar. RemotePlaybackClient sınıfındaki temel oynatma yöntemlerinden birkaçı aşağıda verilmiştir:

  • play(): Uri ile belirtilen belirli bir medya dosyasını oynatır.
  • pause(): Şu anda oynatılan medya parçasını duraklatır.
  • resume() — Duraklatma komutundan sonra mevcut parçayı çalmaya devam eder.
  • seek(): Geçerli parçadaki belirli bir konuma taşınır.
  • release(): Uygulamanız ile uzaktan oynatma cihazı arasındaki bağlantıyı kesin.

Uygulamanızda sağladığınız oynatma kontrollerine işlem eklemek için bu yöntemleri kullanabilirsiniz. Bu yöntemlerin çoğu, oynatma görevinin ilerlemesini izleyebilmeniz veya isteğinin kontrol edilmesi için geri çağırma nesnesi eklemenize de olanak tanır.

RemotePlaybackClient sınıfı, medya sırasının oynatılması ve yönetimi için birden fazla medya öğesinin sıraya alınmasını da destekler.

Örnek kod

Android BasicMediaRouter ve MediaRouter örnekleri, MediaRouter API'nin kullanımını daha ayrıntılı bir şekilde göstermektedir.