Bir Android uygulamasını yayınlayarak etkinleştirin

googlecastnew500.png

Bu kod laboratuvarı, bir Google Cast cihazında içerik oynatmak için mevcut bir Android video uygulamasının nasıl değiştirileceğini size öğretecektir.

Google Cast nedir?

Google Cast, kullanıcıların bir mobil cihazdan TV'ye içerik yayınlamasına olanak tanır. Kullanıcılar daha sonra mobil cihazlarını TV'de medya oynatmak için uzaktan kumanda olarak kullanabilirler.

Google Cast SDK, uygulamanızı bir TV veya ses sistemini kontrol edecek şekilde genişletmenize olanak tanır. Cast SDK, Google Cast Tasarım Kontrol Listesi'ne göre gerekli UI bileşenlerini eklemenize olanak tanır.

Google Cast Tasarım Kontrol Listesi, desteklenen tüm platformlarda Cast kullanıcı deneyimini basit ve öngörülebilir hale getirmek için sağlanmıştır.

Ne inşa edeceğiz?

Bu kod laboratuvarını tamamladığınızda, videoları bir Google Cast cihazına yayınlayabilecek bir Android video uygulamanız olacak.

Ne öğreneceksin

  • Google Cast SDK'sı örnek bir video uygulamasına nasıl eklenir?
  • Google Cast cihazı seçmek için Yayın düğmesi nasıl eklenir?
  • Bir Cast cihazına bağlanma ve bir medya alıcısı başlatma.
  • Bir video nasıl yayınlanır.
  • Uygulamanıza Cast mini kumanda nasıl eklenir?
  • Medya bildirimleri ve kilit ekranı kontrolleri nasıl desteklenir.
  • Genişletilmiş bir denetleyici nasıl eklenir?
  • Giriş katmanı nasıl sağlanır.
  • Cast widget'ları nasıl özelleştirilir.
  • Cast Connect ile nasıl entegre edilir

Neye ihtiyacın olacak

  • En son Android SDK .
  • Android Studio sürüm 3.2+
  • Android 4.1+ Jelly Bean (API seviyesi 16) ile bir mobil cihaz.
  • Mobil cihazınızı geliştirme bilgisayarınıza bağlamak için bir USB veri kablosu.
  • İnternet erişimi ile yapılandırılmış bir Chromecast veya Android TV gibi bir Google Cast cihazı.
  • HDMI girişli bir TV veya monitör.
  • Cast Connect entegrasyonunu test etmek için Google TV'li bir Chromecast gerekir, ancak Codelab'in geri kalanı için isteğe bağlıdır. Bir hesabınız yoksa, bu eğiticinin sonuna doğru Cast Connect Desteği Ekle adımını atlamaktan çekinmeyin.

Deneyim

  • Daha önce Android geliştirme bilgisine sahip olmanız gerekecek.
  • Ayrıca önceden TV izleme bilgisine de ihtiyacınız olacak :)

Bu öğreticiyi nasıl kullanacaksınız?

Sadece baştan sona okuyun Okuyun ve alıştırmaları tamamlayın

Android uygulamaları geliştirme deneyiminizi nasıl değerlendirirsiniz?

Acemi Orta düzey Yetkin

TV izleme deneyiminizi nasıl değerlendirirsiniz?

Acemi Orta düzey Yetkin

Tüm örnek kodu bilgisayarınıza indirebilirsiniz ...

Kaynak Kodunu İndir

ve indirilen zip dosyasını açın.

image04.png

İlk olarak, tamamlanmış örnek uygulamanın neye benzediğini görelim. Uygulama temel bir video oynatıcıdır. Kullanıcı, listeden bir video seçebilir ve ardından videoyu cihazda yerel olarak oynatabilir veya bir Google Cast cihazında yayınlayabilir.

İndirilen kodla birlikte, aşağıdaki talimatlar tamamlanmış örnek uygulamanın Android Studio'da nasıl açılacağını ve çalıştırılacağını açıklar:

Karşılama ekranında Projeyi İçe Aktar'ı veya Dosya> Yeni> Projeyi İçe Aktar ... menü seçeneklerini seçin.

Seçin android_studio_folder.png örnek kod klasöründen app-done dizini ve Tamam'ı tıklayın.

Dosya> b63530213ab28fb8.png Gradle Files ile Projeyi Senkronize Edin .

Android cihazınızda USB hata ayıklamayı etkinleştirin - Android 4.2 ve sonraki sürümlerde Geliştirici seçenekleri ekranı varsayılan olarak gizlidir. Görünür hale getirmek için Ayarlar> Telefon hakkında'ya gidin ve Yapı numarası'na yedi kez dokunun. Önceki ekrana dönün, Sistem> Gelişmiş'e gidin ve alttaki Geliştirici seçeneklerine dokunun, ardından açmak için USB hata ayıklamaya dokunun.

Android cihazınızı takın ve execute.png Android Studio'da çalıştır düğmesi. Birkaç saniye sonra Cast Videos adlı video uygulamasının göründüğünü görmelisiniz.

Video uygulamasında Yayın düğmesini tıklayın ve Google Cast cihazınızı seçin.

Bir video seçin ve oynat düğmesine tıklayın.

Video, Google Cast cihazınızda oynamaya başlayacak.

Genişletilmiş kontrolör görüntülenecektir. Oynatmayı kontrol etmek için oynat / duraklat düğmesini kullanabilirsiniz.

Video listesine geri dönün.

Ekranın altında artık bir mini denetleyici görülebilir. appminicontroller.png

Alıcıdaki videoyu duraklatmak için mini denetleyicideki duraklat düğmesine tıklayın. Videoyu tekrar oynatmaya devam etmek için mini denetleyicideki oynat düğmesine tıklayın.

Mobil cihaz ana sayfa düğmesine tıklayın. Bildirimleri aşağı çekin ve şimdi Cast oturumu için bir bildirim görmelisiniz.

Telefonunuzu kilitleyin ve kilidini açtığınızda, medya oynatmayı kontrol etmek veya yayını durdurmak için kilit ekranında bir bildirim görmelisiniz.

Video uygulamasına dönün ve Google Cast cihazında yayını durdurmak için Yayınla düğmesini tıklayın.

Sıkça Sorulan Sorular

appnocast.png

İndirdiğiniz başlangıç ​​uygulamasına Google Cast desteği eklememiz gerekiyor. Bu kod laboratuvarında kullanacağımız bazı Google Cast terminolojileri:

  • bir gönderen uygulaması bir mobil cihazda veya dizüstü bilgisayarda çalışırsa,
  • Google Cast cihazında bir alıcı uygulaması çalışır.

Artık Android Studio'yu kullanarak başlangıç ​​projesinin üzerine inşa etmeye hazırsınız:

  1. Seçin android_studio_folder.png app-start (karşılama ekranı veya Dosya> Yeni> İthalat Projesi ... menü seçeneği üzerinde Seç İthalat Projesi) sizin örnek kod download dizini.
  2. Tıkla Ekran Görüntüsü 2016-11-18, 11.03.54 AM.png Gradle Files ile Projeyi Senkronize Et düğmesi.
  3. Tıkla execute.png Uygulamayı çalıştırmak ve kullanıcı arayüzünü keşfetmek için Çalıştır düğmesi.

Uygulama tasarımı

Uygulama, uzak bir web sunucusundan bir video listesi getirir ve kullanıcının göz atması için bir liste sağlar. Kullanıcılar, ayrıntıları görmek için bir video seçebilir veya videoyu mobil cihazda yerel olarak oynatabilir.

Uygulama iki ana etkinlikten oluşur: VideoBrowserActivity ve LocalPlayerActivity. Google Cast işlevselliğini entegre etmek için, Aktivitelerin ya AppCompatActivity ya da üst FragmentActivity devralması gerekir. Bu sınırlama, MediaRouteButton'ı ( MediaRouter destek kitaplığında sağlanır ) bir MediaRouteActionProvider olarak eklememiz gerekeceğinden ve bu yalnızca etkinlik yukarıda belirtilen sınıflardan miras alıyorsa işe yarar. MediaRouter destek kitaplığı , gerekli sınıfları sağlayan AppCompat destek kitaplığına bağlıdır.

VideoBrowserActivity

Bu aktivite bir Fragment ( VideoBrowserFragment ) içerir. Bu liste bir tarafından desteklenmektedir ArrayAdapter ( VideoListAdapter ). Videoların listesi ve ilişkili meta verileri, bir JSON dosyası olarak uzak bir sunucuda barındırılır. Bir AsyncTaskLoader ( VideoItemLoader ) bu VideoItemLoader getirir ve MediaItem nesnelerinin bir listesini oluşturmak için onu işler.

MediaItem nesnesi, bir videoyu ve başlığı, açıklaması, akışın URL'si, destekleyen görüntülerin URL'si ve varsa ilişkili Metin Parçaları (altyazılar için) gibi ilişkili meta verilerini modeller. MediaItem böylece nesne, etkinlikler arasında geçirildiğinde MediaItem bir dönüştürmek için yardımcı yöntemleri vardır Bundle tersi ve yardımcısı.

Yükleyici listesini oluşturduğunda MediaItems , bu bu liste geçirir VideoListAdapter sonra sunulur MediaItems liste VideoBrowserFragment . Kullanıcıya, her video için kısa bir açıklama içeren bir video küçük resim listesi sunulur. Bir öğe seçildiğinde karşılık gelen MediaItem bir dönüştürülür Bundle ve geçirilen LocalPlayerActivity .

LocalPlayerActivity

Bu etkinlik, belirli bir video hakkındaki meta verileri görüntüler ve kullanıcının videoyu mobil cihazda yerel olarak oynatmasına izin verir.

Etkinlik, bir VideoView , bazı medya kontrolleri ve seçilen videonun açıklamasını göstermek için bir metin alanı barındırır. Oynatıcı, ekranın üst kısmını kaplayarak, altındaki videonun ayrıntılı açıklaması için yer bırakır. Kullanıcı, videoları oynatabilir / duraklatabilir veya yerel olarak oynatma arayabilir.

Bağımlılıklar

AppCompatActivity kullandığımız için AppCompat destek kitaplığına ihtiyacımız var. Video listesini yönetmek ve listenin eşzamansız olarak resimlerini almak için Volley kitaplığını kullanıyoruz.

Sıkça Sorulan Sorular

appcastbutton.png

Cast özellikli bir uygulama, her bir faaliyetinde Yayın düğmesini görüntüler. Yayın düğmesine tıklamak, bir kullanıcının seçebileceği Yayın cihazlarının bir listesini görüntüler. Kullanıcı, gönderen cihazda yerel olarak içerik oynatıyorsa, bir Cast cihazının seçilmesi o Cast cihazında oynatmayı başlatır veya devam ettirir. Bir Cast oturumu sırasında herhangi bir zamanda, kullanıcı Yayınla düğmesini tıklayabilir ve uygulamanızı Yayın cihazına yayınlamayı durdurabilir. Google Cast Tasarım Kontrol Listesi'nde açıklandığı gibi, uygulamanızın herhangi bir etkinliği sırasında kullanıcının Cast cihazına bağlanabilmesi veya bağlantısını kesebilmesi gerekir .

Bağımlılıklar

Uygulama build.gradle dosyasını gerekli kitaplık bağımlılıklarını içerecek şekilde güncelleyin:

dependencies {
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.mediarouter:mediarouter:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    implementation 'com.google.android.gms:play-services-cast-framework:17.0.0'
    implementation 'com.android.volley:volley:1.1.1'
}

Hatasız proje derlemelerini onaylamak için projeyi senkronize edin.

Başlatma

Cast çerçevesi, tüm Cast etkileşimlerini koordine eden genel bir tekil nesne olan CastContext sahiptir.

Sen uygulamalıdır OptionsProvider tedarik etmek arayüz CastOptions başlatmak için gereken CastContext singleton. En önemli seçenek, Yayın cihazı keşif sonuçlarını filtrelemek ve bir Yayın oturumu başlatıldığında alıcı uygulamasını başlatmak için kullanılan alıcı uygulama kimliğidir.

Kendi Cast özellikli uygulamanızı geliştirirken, bir Cast geliştiricisi olarak kaydolmanız ve ardından uygulamanız için bir uygulama kimliği almanız gerekir. Bu kod laboratuvarı için örnek bir uygulama kimliği kullanacağız.

Aşağıdaki yeni CastOptionsProvider sınıfını projenin com.google.sample.cast.refplayer paketine ekleyin:

package com.google.sample.cast.refplayer;

import com.google.android.gms.cast.framework.CastOptions;
import com.google.android.gms.cast.framework.OptionsProvider;
import com.google.android.gms.cast.framework.SessionProvider;

import android.content.Context;

import java.util.List;


public class CastOptionsProvider implements OptionsProvider {

    @Override
    public CastOptions getCastOptions(Context context) {
        return new CastOptions.Builder()
                .setReceiverApplicationId(context.getString(R.string.app_id))
                .build();
    }

    @Override
    public List<SessionProvider> getAdditionalSessionProviders(Context context) {
        return null;
    }
}

Şimdi OptionsProvider app AndroidManifest.xml dosyasının " application " etiketi içinde AndroidManifest.xml :

<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />

VideoBrowserActivity onCreate yönteminde CastContext :

import com.google.android.gms.cast.framework.CastContext;

private CastContext mCastContext;

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

    mCastContext = CastContext.getSharedInstance(this);
}

Aynı başlatma mantığını LocalPlayerActivity .

Yayın düğmesi

Artık CastContext başlatıldığına göre, kullanıcının bir Yayın cihazı seçmesine izin vermek için Yayınla düğmesini eklememiz gerekiyor. Oyuncular düğmesi tarafından uygulanan MediaRouteButton gelen MediaRouter destek kütüphanesine. Eğer aktivite ekleyebileceğiniz herhangi bir işlem simgesi gibi (ya bir kullanarak ActionBar veyaToolbar Menünüzde karşılık gelen menü öğesi eklemek için, önce ihtiyaç).

Düzen res/menu/browse.xml dosyası ve eklemek MediaRouteActionProvider ayarları öğesinin önce menüde öğeyi:

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

Geçersiz kıl onCreateOptionsMenu() metodu VideoBrowserActivity kullanılarak CastButtonFactory kadar tel MediaRouteButton Döküm çerçevesine:

import com.google.android.gms.cast.framework.CastButtonFactory;

private MenuItem mediaRouteMenuItem;

public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.browse, menu);
    mediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu, R.id.media_route_menu_item);
    return true;
}

LocalPlayerActivity onCreateOptionsMenu benzer şekilde geçersiz kılın.

Tıkla execute.png Uygulamayı mobil cihazınızda çalıştırmak için Çalıştır düğmesi. Uygulamanın işlem çubuğunda bir Yayın düğmesi görmelisiniz ve üzerine tıkladığınızda, yerel ağınızdaki Yayın cihazlarını listeleyecektir. Cihaz keşfi, CastContext tarafından otomatik olarak yönetilir. Yayın cihazınızı seçin, örnek alıcı uygulaması Yayın cihazına yüklenecektir. Göz atma etkinliği ile yerel oynatıcı etkinliği arasında gezinebilirsiniz ve Yayın düğmesinin durumu senkronize tutulur.

Medya oynatma için herhangi bir destek sağlamadık, bu nedenle Cast cihazında henüz video oynatamazsınız. Bağlantıyı kesmek için Yayınla düğmesine tıklayın.

appminicontroller.png

Örnek uygulamayı bir Cast cihazında uzaktan video oynatmak için genişleteceğiz. Bunu yapmak için Cast çerçevesi tarafından oluşturulan çeşitli olayları dinlememiz gerekir.

Medya döküm

Yüksek düzeyde, bir medyayı bir Cast cihazında oynatmak istiyorsanız, şunları yapmanız gerekir:

  1. Bir medya öğesini modelleyen bir MediaInfo nesnesi oluşturun.
  2. Cast cihazına bağlanın ve alıcı uygulamanızı başlatın.
  3. MediaInfo nesnesini alıcınıza yükleyin ve içeriği oynatın.
  4. Medya durumunu takip edin.
  5. Kullanıcı etkileşimlerine göre alıcıya oynatma komutları gönderin.

Önceki bölümde 2. Adımı zaten yaptık. 3. Adımın Cast çerçevesiyle yapılması kolaydır. Adım 1, bir nesneyi diğerine eşlemek anlamına gelir; MediaInfo , Cast çerçevesinin anladığı bir şeydir ve MediaItem , uygulamamızın bir medya öğesi için kapsüllemesidir; Bir MediaItem bir MediaInfo kolayca eşleştirebiliriz.

Örnek uygulama LocalPlayerActivity , şu numaralandırmayı kullanarak yerel ve uzaktan oynatma arasında zaten ayrım yapmaktadır:

private PlaybackLocation mLocation;

public enum PlaybackLocation {
    LOCAL,
    REMOTE
}

Bu kod laboratuarında, tüm örnek oynatıcı mantığının tam olarak nasıl çalıştığını anlamanız sizin için önemli değildir. Uygulamanızın medya oynatıcısının benzer şekilde iki oynatma konumundan haberdar olması için değiştirilmesi gerekeceğini anlamak önemlidir.

Şu anda yerel oynatıcı her zaman yerel oynatma durumundadır çünkü henüz Casting durumları hakkında hiçbir şey bilmiyor. Kullanıcı arayüzünü, Cast çerçevesinde gerçekleşen durum geçişlerine göre güncellememiz gerekiyor. Örneğin, yayına başlarsak, yerel oynatmayı durdurmalı ve bazı kontrolleri devre dışı bırakmalıyız. Benzer şekilde, bu aktivitede olduğumuzda yayını durdurursak, yerel oynatmaya geçmemiz gerekir. Bunu halletmek için Cast çerçevesi tarafından oluşturulan çeşitli olayları dinlememiz gerekir.

Yayın oturumu yönetimi

Cast çerçevesi için bir Cast oturumu, bir cihaza bağlanma, başlatma (veya katılma), bir alıcı uygulamasına bağlanma ve uygunsa bir medya kontrol kanalını başlatma adımlarını birleştirir. Medya kontrol kanalı, Cast çerçevesinin alıcı medya oynatıcısından mesajları nasıl gönderip aldığıdır.

Yayın oturumu, kullanıcı Yayınla düğmesinden bir cihaz seçtiğinde otomatik olarak başlatılacak ve kullanıcı bağlantısı kesildiğinde otomatik olarak durdurulacaktır. Ağ sorunları nedeniyle bir alıcı oturumuna yeniden bağlanma da Cast SDK tarafından otomatik olarak ele alınır.

Dökme oturumları tarafından yönetilir SessionManager üzerinden erişilebilir, CastContext.getSessionManager() . SessionManagerListener geri aramaları, oluşturma, askıya alma, devam ettirme ve sonlandırma gibi oturum olaylarını izlemek için kullanılabilir.

En bir ekleyelim SessionManagerListener için LocalPlayerActivity :

import com.google.android.gms.cast.framework.CastSession;
import com.google.android.gms.cast.framework.SessionManagerListener;

private CastSession mCastSession;
private SessionManagerListener<CastSession> mSessionManagerListener;

private void setupCastListener() {
    mSessionManagerListener = new SessionManagerListener<CastSession>() {

        @Override
        public void onSessionEnded(CastSession session, int error) {
            onApplicationDisconnected();
        }

        @Override
        public void onSessionResumed(CastSession session, boolean wasSuspended) {
            onApplicationConnected(session);
        }

        @Override
        public void onSessionResumeFailed(CastSession session, int error) {
            onApplicationDisconnected();
        }

        @Override
        public void onSessionStarted(CastSession session, String sessionId) {
            onApplicationConnected(session);
        }

        @Override
        public void onSessionStartFailed(CastSession session, int error) {
            onApplicationDisconnected();
        }

        @Override
        public void onSessionStarting(CastSession session) {}

        @Override
        public void onSessionEnding(CastSession session) {}

        @Override
        public void onSessionResuming(CastSession session, String sessionId) {}

        @Override
        public void onSessionSuspended(CastSession session, int reason) {}

        private void onApplicationConnected(CastSession castSession) {
            mCastSession = castSession;
            if (null != mSelectedMedia) {

                if (mPlaybackState == PlaybackState.PLAYING) {
                    mVideoView.pause();
                    loadRemoteMedia(mSeekbar.getProgress(), true);
                    return;
                } else {
                    mPlaybackState = PlaybackState.IDLE;
                    updatePlaybackLocation(PlaybackLocation.REMOTE);
                }
            }
            updatePlayButton(mPlaybackState);
            supportInvalidateOptionsMenu();
        }

        private void onApplicationDisconnected() {
            updatePlaybackLocation(PlaybackLocation.LOCAL);
            mPlaybackState = PlaybackState.IDLE;
            mLocation = PlaybackLocation.LOCAL;
            updatePlayButton(mPlaybackState);
            supportInvalidateOptionsMenu();
        }
    };
}

LocalPlayerActivity etkinliğinde, yerel oynatıcıya veya yerel oynatıcıdan geçiş yapabilmemiz için Cast cihazına bağlandığımızda veya bağlantımız kesildiğinde bilgilendirilmek isteriz. Bağlantının yalnızca uygulamanızın mobil cihazınızda çalışan örneğiyle değil, aynı zamanda farklı bir mobil cihazda çalışan başka bir (veya başka) uygulamanız tarafından da kesilebileceğini unutmayın.

Şu anda aktif olan oturuma SessionManager.getCurrentSession() olarak erişilebilir. Oturumlar, kullanıcıların Yayın iletişim kutuları ile etkileşimlerine yanıt olarak otomatik olarak oluşturulur ve parçalanır.

Oturum dinleyicimizi kaydetmeli ve aktivitede kullanacağımız bazı değişkenleri başlatmalıyız. LocalPlayerActivity onCreate yöntemini şu şekilde değiştirin:

import com.google.android.gms.cast.framework.CastContext;
import com.google.android.gms.cast.framework.CastSession;

private CastContext mCastContext;
private CastSession mCastSession;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    setupControlsCallbacks();
    setupCastListener();
    mCastContext = CastContext.getSharedInstance(this);
    mCastSession = mCastContext.getSessionManager().getCurrentCastSession();
    Bundle bundle = getIntent().getExtras();
    ...
    } else {
        if (mCastSession != null && mCastSession.isConnected()) {
            updatePlaybackLocation(PlaybackLocation.REMOTE);
        } else {
            updatePlaybackLocation(PlaybackLocation.LOCAL);
        }
        mPlaybackState = PlaybackState.IDLE;
        updatePlayButton(mPlaybackState);
    }
    ...
}

Medya yükleme

Cast SDK'da RemoteMediaClient , alıcıda uzaktan medya oynatımını yönetmek için bir dizi uygun API sağlar. Bir İçin CastSession destekleri medya oynatma olduğunu, bir örneği RemoteMediaClient SDK tarafından otomatik olarak oluşturulur. CastSession örneğinde getRemoteMediaClient() yöntemi çağrılarak erişilebilir. Şu anda seçili videoyu alıcıya yüklemek için LocalPlayerActivity aşağıdaki yöntemleri ekleyin:

import com.google.android.gms.cast.framework.media.RemoteMediaClient;
import com.google.android.gms.cast.MediaInfo;
import com.google.android.gms.cast.MediaLoadOptions;
import com.google.android.gms.cast.MediaMetadata;
import com.google.android.gms.common.images.WebImage;

private void loadRemoteMedia(int position, boolean autoPlay) {
    if (mCastSession == null) {
        return;
    }
    RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
    if (remoteMediaClient == null) {
        return;
    }
    remoteMediaClient.load(new MediaLoadRequestData.Builder()
                .setMediaInfo(buildMediaInfo())
                .setAutoplay(autoPlay)
                .setCurrentTime(position).build());
}

private MediaInfo buildMediaInfo() {
    MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);

    movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, mSelectedMedia.getStudio());
    movieMetadata.putString(MediaMetadata.KEY_TITLE, mSelectedMedia.getTitle());
    movieMetadata.addImage(new WebImage(Uri.parse(mSelectedMedia.getImage(0))));
    movieMetadata.addImage(new WebImage(Uri.parse(mSelectedMedia.getImage(1))));

    return new MediaInfo.Builder(mSelectedMedia.getUrl())
            .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
            .setContentType("videos/mp4")
            .setMetadata(movieMetadata)
            .setStreamDuration(mSelectedMedia.getDuration() * 1000)
            .build();
}

Şimdi, uzaktan oynatmayı desteklemek için Yayın oturumu mantığını kullanmak için çeşitli mevcut yöntemleri güncelleyin:

private void play(int position) {
    startControllersTimer();
    switch (mLocation) {
        case LOCAL:
            mVideoView.seekTo(position);
            mVideoView.start();
            break;
        case REMOTE:
            mPlaybackState = PlaybackState.BUFFERING;
            updatePlayButton(mPlaybackState);
            mCastSession.getRemoteMediaClient().seek(position);
            break;
        default:
            break;
    }
    restartTrickplayTimer();
}
private void togglePlayback() {
...
case IDLE:
...
    case REMOTE:
        if (mCastSession != null && mCastSession.isConnected()) {
            loadRemoteMedia(mSeekbar.getProgress(), true);
        }
        break;
     default:
...
}
private void onPause() {
...
    mCastContext.getSessionManager().removeSessionManagerListener(
                mSessionManagerListener, CastSession.class);
}
protected void onResume() {
    Log.d(TAG, "onResume() was called");
    mCastContext.getSessionManager().addSessionManagerListener(
            mSessionManagerListener, CastSession.class);
    if (mCastSession != null && mCastSession.isConnected()) {
        updatePlaybackLocation(PlaybackLocation.REMOTE);
    } else {
        updatePlaybackLocation(PlaybackLocation.LOCAL);
    }
    super.onResume();
}

updatePlayButton yöntemi için, isConnected değişkeninin değerini değiştirin:

private void updatePlayButton(PlaybackState state) {
    ...
    boolean isConnected = (mCastSession != null)
                && (mCastSession.isConnected() || 
                    mCastSession.isConnecting());
    ...
}

Şimdi tıklayın execute.png Uygulamayı mobil cihazınızda çalıştırmak için Çalıştır düğmesi. Cast cihazınıza bağlanın ve bir video oynatmaya başlayın. Alıcıda oynatılan videoyu görmelisiniz.

Yayın Tasarımı Kontrol Listesi, tüm Cast uygulamalarının, kullanıcı mevcut içerik sayfasından ayrıldığında görünen mini denetleyici sağlamasını gerektirir. Mini denetleyici, mevcut Cast oturumu için anında erişim ve görünür bir hatırlatıcı sağlar.

minicontroller.png

Cast SDK, mini denetleyiciyi göstermek istediğiniz etkinliklerin uygulama düzeni dosyasına eklenebilen MiniControllerFragment adlı özel bir görünüm sağlar.

Aşağıdaki parça tanımını hem res/layout/player_activity.xml hem de res/layout/player_activity.xml res/layout/video_browser.xml :

<fragment
    android:id="@+id/castMiniController"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:visibility="gone"
    class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment"/>

Tıkla execute.png Uygulamayı çalıştırmak ve bir video yayınlamak için Çalıştır düğmesi. Alıcıda oynatma başladığında, her etkinliğin altında mini denetleyicinin göründüğünü görmelisiniz. Uzaktan oynatmayı mini denetleyiciyi kullanarak kontrol edebilirsiniz. Göz atma etkinliği ve yerel oynatıcı etkinliği arasında gezinirseniz, mini denetleyici durumu alıcı ortam oynatma durumuyla senkronize kalmalıdır.

Google Cast tasarım kontrol listesi, bir bildirimden ve kilit ekranından medya kontrollerini uygulamak için bir gönderen uygulaması gerektirir.

appnotification.png

Cast SDK, gönderen uygulamanın bildirim ve kilit ekranı için medya kontrolleri oluşturmasına yardımcı olmak için bir MediaNotificationService sağlar. Hizmet, kademeli olarak uygulamanızın manifestinde otomatik olarak birleştirilir.

MediaNotificationService , gönderen yayın yaparken arka planda çalışacak ve geçerli yayın öğesi, bir oynat / duraklat düğmesi ve bir durdur düğmesi hakkında bir resim küçük resmi ve meta veriler içeren bir bildirim gösterecektir.

Bildirim ve kilit ekranı kontrolleri ile etkinleştirilebilir CastOptions başlatırken CastContext . Bildirim ve kilit ekranı için medya kontrolleri varsayılan olarak açıktır. Bildirim açık olduğu sürece kilit ekranı özelliği açıktır.

CastOptionsProvider ve getCastOptions uygulamasını bu kodla eşleşecek şekilde değiştirin:

import com.google.android.gms.cast.framework.media.CastMediaOptions;
import com.google.android.gms.cast.framework.media.NotificationOptions;

public CastOptions getCastOptions(Context context) {
    NotificationOptions notificationOptions = new NotificationOptions.Builder()
            .setTargetActivityClassName(VideoBrowserActivity.class.getName())
            .build();
    CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .build();

    return new CastOptions.Builder()
            .setReceiverApplicationId(context.getString(R.string.app_id))
            .setCastMediaOptions(mediaOptions)
            .build();
}

Tıkla execute.png Uygulamayı mobil cihazınızda çalıştırmak için Çalıştır düğmesi. Bir video yayınlayın ve örnek uygulamadan uzaklaşın. Şu anda alıcıda oynatılan video için bir bildirim olmalıdır. Mobil cihazınızı kilitlediğinizde kilit ekranı artık Cast cihazında medya oynatma kontrollerini görüntüleyecektir.

applockscreen.png

Google Cast tasarım kontrol listesi, bir gönderen uygulamasının mevcut kullanıcılara, gönderen uygulamanın artık yayınlamayı desteklediğini ve ayrıca Google Cast'te yeni olan kullanıcılara yardımcı olduğunu bildirmek için Yayın düğmesini tanıtmasını gerektirir.

appcling.png

Cast SDK, kullanıcılara ilk gösterildiğinde Yayınla düğmesini vurgulamak için kullanılabilen özel bir IntroductoryOverlay Görünümü sağlar. Aşağıdaki kodu VideoBrowserActivity ekleyin:

import com.google.android.gms.cast.framework.IntroductoryOverlay;
import android.os.Handler;

private IntroductoryOverlay mIntroductoryOverlay;

private void showIntroductoryOverlay() {
    if (mIntroductoryOverlay != null) {
        mIntroductoryOverlay.remove();
    }
    if ((mediaRouteMenuItem != null) && mediaRouteMenuItem.isVisible()) {
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                mIntroductoryOverlay = new IntroductoryOverlay.Builder(
                        VideoBrowserActivity.this, mediaRouteMenuItem)
                        .setTitleText("Introducing Cast")
                        .setSingleTime()
                        .setOnOverlayDismissedListener(
                                new IntroductoryOverlay.OnOverlayDismissedListener() {
                                    @Override
                                    public void onOverlayDismissed() {
                                        mIntroductoryOverlay = null;
                                    }
                                })
                        .build();
                mIntroductoryOverlay.show();
            }
        });
    }
}

Şimdi, bir CastStateListener ekleyin ve aşağıdakilerle eşleşecek şekilde onCreate yöntemini değiştirerek bir Cast cihazı kullanılabilir olduğunda showIntroductoryOverlay yöntemini çağırın:

import com.google.android.gms.cast.framework.CastState;
import com.google.android.gms.cast.framework.CastStateListener;

private CastStateListener mCastStateListener;

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

    mCastStateListener = new CastStateListener() {
        @Override
        public void onCastStateChanged(int newState) {
            if (newState != CastState.NO_DEVICES_AVAILABLE) {
                showIntroductoryOverlay();
            }
        }
    };
    mCastContext = CastContext.getSharedInstance(this);
}

@Override
protected void onResume() {
    mCastContext.addCastStateListener(mCastStateListener);
    super.onResume();
}

@Override
protected void onPause() {
    mCastContext.removeCastStateListener(mCastStateListener);
    super.onPause();
}

Tıkla execute.png Uygulamayı mobil cihazınızda çalıştırmak için Çalıştır düğmesi ve giriş katmanını görmeniz gerekir (katman görüntülenmezse uygulama verilerini temizleyin).

Google Cast tasarım kontrol listesi, yayınlanan medya için genişletilmiş denetleyici sağlamak için bir gönderen uygulaması gerektirir. Genişletilmiş denetleyici, mini denetleyicinin tam ekran sürümüdür.

appexpandedcontrols.png

Cast SDK, ExpandedControllerActivity adlı genişletilmiş denetleyici için bir pencere öğesi sağlar. Bu, bir Yayınla düğmesi eklemek için alt sınıflara ayırmanız gereken soyut bir sınıftır.

Birincisi, adı verilen yeni bir menü kaynak dosyası oluşturmak expanded_controller.xml Yayınla düğmesine sağlamak için genişletilmiş denetleyici için:

<?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>

com.google.sample.cast.refplayer.expandedcontrols paketinde ExpandedControlsActivity adlı yeni bir sınıf oluşturun.

package com.google.sample.cast.refplayer.expandedcontrols;

import com.google.android.gms.cast.framework.CastButtonFactory;
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity;
import com.google.sample.cast.refplayer.R;
import android.view.Menu;

public class ExpandedControlsActivity extends ExpandedControllerActivity {

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.expanded_controller, menu);
        CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item);
        return true;
    }
}

Şimdi application etiketindeki uygulama bildiriminde ExpandedControlsActivity :

<application>
    ...
    <activity
        android:name=".expandedcontrols.ExpandedControlsActivity"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:theme="@style/Theme.CastVideosDark"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
        </intent-filter>
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.google.sample.cast.refplayer.VideoBrowserActivity"/>
    </activity>
    ...
</application>

CastOptionsProvider ve hedef etkinliği ExpandedControlsActivity ayarlamak için NotificationOptions ve CastMediaOptions değiştirin:

import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity;

public CastOptions getCastOptions(Context context) {
    NotificationOptions notificationOptions = new NotificationOptions.Builder()
            .setTargetActivityClassName(ExpandedControlsActivity.class.getName())
            .build();
    CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
            .setNotificationOptions(notificationOptions)
            .setExpandedControllerActivityClassName(ExpandedControlsActivity.class.getName())
            .build();

    return new CastOptions.Builder()
            .setReceiverApplicationId(context.getString(R.string.app_id))
            .setCastMediaOptions(mediaOptions)
            .build();
}

Uzak medya yüklendiğinde ExpandedControlsActivity görüntülemek için LocalPlayerActivity loadRemoteMedia yöntemini güncelleyin:

import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity;

private void loadRemoteMedia(int position, boolean autoPlay) {
    if (mCastSession == null) {
        return;
    }
    final RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
    if (remoteMediaClient == null) {
        return;
    }
    remoteMediaClient.registerCallback(new RemoteMediaClient.Callback() {
        @Override
        public void onStatusUpdated() {
            Intent intent = new Intent(LocalPlayerActivity.this, ExpandedControlsActivity.class);
            startActivity(intent);
            remoteMediaClient.unregisterCallback(this);
        }
    });

    remoteMediaClient.load(new MediaLoadRequestData.Builder()
                .setMediaInfo(buildMediaInfo())
                .setAutoplay(autoPlay)
                .setCurrentTime(position).build());
}

Tıkla execute.png Uygulamayı mobil cihazınızda çalıştırmak ve bir video yayınlamak için Çalıştır düğmesi. Genişletilmiş denetleyiciyi görmelisiniz. Video listesine geri dönün ve mini denetleyiciye tıkladığınızda, genişletilmiş denetleyici tekrar yüklenecektir. Bildirimi görmek için uygulamadan uzaklaşın. Genişletilmiş denetleyiciyi yüklemek için bildirim resmine tıklayın.

Cast Connect kitaplığı, mevcut gönderen uygulamaların Android TV uygulamalarıyla Cast protokolü aracılığıyla iletişim kurmasına olanak tanır. Cast Connect, Android TV uygulamanızın alıcı görevi görmesiyle Cast altyapısının üzerine kurulur.

Bağımlılıklar

build.gradle dosyanızda aşağıdaki bağımlılıkların bildirildiğinden emin olun:

implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.mediarouter:mediarouter:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.gms:play-services-cast-framework:19.0.0'

Başlatma ayarları

Android Alıcısı olarak da adlandırılan Android TV uygulamasını başlatmak için LaunchOptions nesnesinde setAndroidReceiverCompatible bayrağını true olarak ayarlamamız gerekir. Bu LaunchOptions nesnesi, alıcının nasıl başlatılacağını ve CastOptions tarafından döndürülen CastOptions nasıl aktarılacağını CastOptionsProvider.java . Yukarıda belirtilen işaretin false ayarlanması, Cast Developer Console'da tanımlanan Uygulama Kimliği için web alıcısını başlatır.

CastOptionsProvider.java dosyasına aşağıdakileri ekleyin:

LaunchOptions launchOptions = new LaunchOptions.Builder()
              .setAndroidReceiverCompatible(true)
              .build();
    return new CastOptions.Builder()
        .setLaunchOptions(launchOptions)
        ...
        .build();

Başlatma Kimlik Bilgilerini Ayarlama

Gönderen tarafında, oturuma kimin katıldığını göstermek için CredentialsData belirtebilirsiniz. credentials , ATV uygulamanız anlayabildiği sürece kullanıcı tarafından tanımlanabilen bir dizedir. CredentialsData yalnızca başlatma veya katılma sırasında Android TV uygulamanıza aktarılır. Bağlıyken yeniden ayarlarsanız, Android TV uygulamanıza aktarılmaz.

Başlatma Kimlik CredentialsData ayarlamak için LaunchOptions tanımlanması ve LaunchOptions nesnesine aktarılması gerekir. CastOptionsProvider.java sınıfınıza aşağıdaki kodu ekleyin:

CredentialsData credentialsData = new CredentialsData.Builder()
       .setCredentials("{\"userId\": \"abc\"}")
       .build();
LaunchOptions launchOptions = new LaunchOptions.Builder()
       ...
       .setCredentialsData(credentialsData)
       .build();

LoadRequest'te Kimlik Bilgilerini Ayarlayın

Web Alıcısı uygulamanızın ve Android TV uygulamanızın credentials farklı şekilde ele alması durumunda, her biri için ayrı credentials tanımlamanız gerekebilir. Bunu halletmek için, LocalPlayerActivity.java sınıfınıza loadRemoteMedia işlevi altına aşağıdaki kodu ekleyin:

remoteMediaClient.load(new MediaLoadRequestData.Builder()
       ...
       .setCredentials("user-credentials")
       .setAtvCredentials("atv-user-credentials")
       .build());

Göndericinizin yayın yaptığı alıcı uygulamasına bağlı olarak, SDK artık geçerli oturum için hangi kimlik bilgilerinin kullanılacağını otomatik olarak işleyecektir.

Cast Connect'i Test Etme

Android TV APK'sını Google TV ile Chromecast'e yükleme adımları

  1. Android TV cihazınızın IP Adresini bulun. Genellikle, Ayarlar> Ağ ve İnternet> (Cihazınızın bağlı olduğu ağ adı) altında bulunur . Sağ tarafta ayrıntıları ve cihazınızın ağdaki IP'sini gösterecektir.
  2. Terminali kullanarak ADB aracılığıyla cihazınıza bağlanmak için cihazınızın IP adresini kullanın:
$ adb connect <device_ip_address>:5555
  1. Terminal pencerenizden, bu kod laboratuarının başlangıcında indirdiğiniz kod laboratuvarı örnekleri için en üst düzey klasöre gidin. Örneğin:
$ cd Desktop/android_codelab_src
  1. Bu klasördeki .apk dosyasını aşağıdakileri çalıştırarak Android TV'nize yükleyin:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Artık Android TV cihazınızda Uygulamalarınız menüsünde Video Yayınlama adına göre bir uygulamayı görebiliyor olmanız gerekir.
  2. Android Studio projenize geri dönün ve gönderen uygulamasını fiziksel mobil cihazınıza yüklemek ve çalıştırmak için Çalıştır düğmesini tıklayın. Sağ üst köşedeki yayın simgesine tıklayın ve mevcut seçeneklerden Android TV cihazınızı seçin. Şimdi Android TV cihazınızda başlatılan Android TV uygulamasını görmelisiniz ve bir video oynatmak, Android TV uzaktan kumandanızı kullanarak video oynatmayı kontrol etmenizi sağlamalıdır.

Renkleri ayarlayarak, düğmeleri, metni ve küçük resim görünümünü şekillendirerek ve görüntülenecek düğme türlerini seçerek Cast widget'larını özelleştirebilirsiniz.

res/values/styles_castvideo.xml güncelleyin

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
    ...
    <item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
    <item name="castIntroOverlayStyle">@style/CustomCastIntroOverlay</item>
    <item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
    <item name="castExpandedControllerStyle">@style/CustomCastExpandedController</item>
    <item name="castExpandedControllerToolbarStyle">
        @style/ThemeOverlay.AppCompat.ActionBar
    </item>
    ...
</style>

Aşağıdaki özel temaları bildirin:

<!-- Customize Cast Button -->
<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
    <item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>
<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
    <item name="mediaRouteButtonTint">#EEFF41</item>
</style>

<!-- Customize Introductory Overlay -->
<style name="CustomCastIntroOverlay" parent="CastIntroOverlay">
    <item name="castButtonTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Button</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Title</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Button" parent="android:style/TextAppearance">
    <item name="android:textColor">#FFFFFF</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Title" parent="android:style/TextAppearance.Large">
    <item name="android:textColor">#FFFFFF</item>
</style>

<!-- Customize Mini Controller -->
<style name="CustomCastMiniController" parent="CastMiniController">
    <item name="castShowImageThumbnail">true</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.AppCompat.Subhead</item>
    <item name="castSubtitleTextAppearance">@style/TextAppearance.AppCompat.Caption</item>
    <item name="castBackground">@color/accent</item>
    <item name="castProgressBarColor">@color/orange</item>
</style>

<!-- Customize Expanded Controller -->
<style name="CustomCastExpandedController" parent="CastExpandedController">
    <item name="castButtonColor">#FFFFFF</item>
    <item name="castPlayButtonDrawable">@drawable/cast_ic_expanded_controller_play</item>
    <item name="castPauseButtonDrawable">@drawable/cast_ic_expanded_controller_pause</item>
    <item name="castStopButtonDrawable">@drawable/cast_ic_expanded_controller_stop</item>
</style>

Artık Android'de Cast SDK widget'larını kullanarak bir video uygulamasını nasıl Cast-etkinleştireceğinizi biliyorsunuz.

GitHub'daki örnek uygulamalarımıza bir göz atın: github.com/googlecast .