TV giriş hizmeti geliştirme

TV girişi hizmeti, bir medya akışı kaynağını temsil eder ve medya içeriğinizi kanallar ve programlar olarak doğrusal bir yayın TV şeklinde sunmanıza olanak tanır. TV giriş hizmetiyle ebeveyn denetimi, program rehberi bilgileri ve içerik derecelendirmeleri sağlayabilirsiniz. TV giriş hizmeti, Android sistem TV uygulamasıyla çalışır. Bu uygulama, kanal içeriğini TV'de kontrol edip sunar. Sistem TV uygulaması, cihaza özel olarak geliştirilmiştir ve üçüncü taraf uygulamalar tarafından değiştirilemez. TV Input Framework (TIF) mimarisi ve bileşenleri hakkında daha fazla bilgi için TV Input Framework başlıklı makaleyi inceleyin.

TIF Companion Library'yi kullanarak TV giriş hizmeti oluşturma

TIF Companion Library, yaygın TV giriş hizmeti özelliklerinin genişletilebilir uygulamalarını sağlayan bir çerçevedir. Yalnızca Android 5.0 (API düzeyi 21) ile Android 7.1 (API düzeyi 25) arasındaki sürümler için kanallar oluşturmak üzere OEM'ler tarafından kullanılmak üzere tasarlanmıştır.

Projenizi güncelleme

TIF Companion Library, androidtv-sample-inputs deposunda OEM'ler tarafından eski kullanım için kullanılabilir. Kitaplığın bir uygulamaya nasıl dahil edileceğine dair örnek için bu depoya bakın.

TV giriş hizmetinizi manifest dosyasında belirtin.

Uygulamanız, sistemin uygulamanıza erişmek için kullandığı TvInputService ile uyumlu bir hizmet sağlamalıdır. TIF Companion Library, TvInputService için özelleştirebileceğiniz varsayılan bir uygulama sağlayan BaseTvInputService sınıfını sunar. BaseTvInputService sınıfının bir alt sınıfını oluşturun ve alt sınıfı manifest'inizde hizmet olarak bildirin.

Manifest bildiriminde, hizmetin TV girişini sisteme bağlamasına izin vermek için BIND_TV_INPUT iznini belirtin. Bağlama işlemini bir sisteme ait hizmet yapar ve BIND_TV_INPUT iznine sahiptir. Sistem TV uygulaması, TvInputManager arayüzü aracılığıyla TV giriş hizmetlerine istek gönderir.

Servis bildiriminizde, intent ile gerçekleştirilecek eylem olarak TvInputService belirten bir intent filtresi ekleyin. Ayrıca hizmet meta verilerini ayrı bir XML kaynağı olarak tanımlayın. Aşağıdaki örnekte hizmet bildirimi, intent filtresi ve hizmet meta verileri bildirimi gösterilmektedir:

<service android:name=".rich.RichTvInputService"
    android:label="@string/rich_input_label"
    android:permission="android.permission.BIND_TV_INPUT">
    <!-- Required filter used by the system to launch our account service. -->
    <intent-filter>
        <action android:name="android.media.tv.TvInputService" />
    </intent-filter>
    <!-- An XML file which describes this input. This provides pointers to
    the RichTvInputSetupActivity to the system/TV app. -->
    <meta-data
        android:name="android.media.tv.input"
        android:resource="@xml/richtvinputservice" />
</service>

Hizmet meta verilerini ayrı bir XML dosyasında tanımlayın. Hizmet meta veri XML dosyası, TV girişinin ilk yapılandırmasını ve kanal taramasını açıklayan bir kurulum arayüzü içermelidir. Meta veri dosyasında, kullanıcıların içerik kaydedip kaydedemeyeceğini belirten bir işaret de bulunmalıdır. Uygulamanızda içerik kaydını destekleme hakkında daha fazla bilgi için İçerik kaydını destekleme başlıklı makaleyi inceleyin.

Hizmet meta veri dosyası, uygulamanızın XML kaynakları dizininde bulunur ve manifest'te beyan ettiğiniz kaynağın adıyla eşleşmelidir. Önceki örnekteki manifest girişlerini kullanarak res/xml/richtvinputservice.xml konumunda aşağıdaki içeriklere sahip bir XML dosyası oluşturursunuz:

<?xml version="1.0" encoding="utf-8"?>
<tv-input xmlns:android="http://schemas.android.com/apk/res/android"
  android:canRecord="true"
  android:setupActivity="com.example.android.sampletvinput.rich.RichTvInputSetupActivity" />

Kanalları tanımlama ve kurulum etkinliğinizi oluşturma

TV giriş hizmetiniz, kullanıcıların sistem TV uygulaması üzerinden eriştiği en az bir kanal tanımlamalıdır. Kanallarınızı sistem veritabanına kaydetmeli ve sistemin uygulamanız için kanal bulamadığında çağırdığı bir kurulum etkinliği sağlamalısınız.

Öncelikle, uygulamanızın sistemdeki Elektronik Program Kılavuzu'ndan (EPG) okuma ve EPG'ye yazma işlemlerini yapmasını sağlayın. EPG'nin verileri, kullanıcının erişebileceği kanalları ve programları içerir. Uygulamanızın bu işlemleri gerçekleştirmesini ve cihaz yeniden başlatıldıktan sonra EPG ile senkronize olmasını sağlamak için uygulama manifestinize aşağıdaki öğeleri ekleyin:

<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>

Uygulamanızın Google Play Store'da Android TV'de içerik kanalları sağlayan bir uygulama olarak gösterilmesi için aşağıdaki öğeyi ekleyin:

<uses-feature
    android:name="android.software.live_tv"
    android:required="true" />

Ardından, EpgSyncJobService sınıfını genişleten bir sınıf oluşturun. Bu soyut sınıf, sistem veritabanında kanallar oluşturan ve güncelleyen bir iş hizmeti oluşturmanıza olanak tanır.

Alt sınıfınızda, getChannels içinde kanallarınızın tam listesini oluşturup döndürün. Kanallarınız bir XMLTV dosyasından geliyorsa XmlTvParser sınıfını kullanın. Aksi takdirde, Channel.Builder sınıfını kullanarak kanalları programatik olarak oluşturun.

Sistem, her kanal için getProgramsForChannel işlevini çağırarak kanalda belirli bir zaman aralığında görüntülenebilecek programların listesini ister. Kanal için Program nesnelerin listesini döndürür. XMLTV dosyasından program almak için XmlTvParser sınıfını kullanın veya Program.Builder sınıfını kullanarak programları programatik olarak oluşturun.

Her Program nesnesi için programın video türü gibi program bilgilerini ayarlamak üzere bir InternalProviderData nesnesi kullanın. Kanalın döngü halinde tekrarlamasını istediğiniz program sayısı sınırlıysa programınızla ilgili bilgileri ayarlarken InternalProviderData.setRepeatable yöntemini true değeriyle kullanın.

İş hizmetini uyguladıktan sonra uygulama manifestinize ekleyin:

<service
    android:name=".sync.SampleJobService"
    android:permission="android.permission.BIND_JOB_SERVICE"
    android:exported="true" />

Son olarak, bir kurulum etkinliği oluşturun. Kurulum etkinliğiniz, kanal ve program verilerini senkronize etmenin bir yolunu sağlamalıdır. Bunu yapmanın bir yolu, kullanıcının etkinlikteki kullanıcı arayüzünü kullanmasıdır. Etkinlik başladığında uygulamanın bunu otomatik olarak yapmasını da sağlayabilirsiniz. Kurulum etkinliğinin kanal ve program bilgilerini senkronize etmesi gerektiğinde uygulama, iş hizmetini başlatmalıdır:

Kotlin

val inputId = getActivity().intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID)
EpgSyncJobService.cancelAllSyncRequests(getActivity())
EpgSyncJobService.requestImmediateSync(
        getActivity(),
        inputId,
        ComponentName(getActivity(), SampleJobService::class.java)
)

Java

String inputId = getActivity().getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID);
EpgSyncJobService.cancelAllSyncRequests(getActivity());
EpgSyncJobService.requestImmediateSync(getActivity(), inputId,
        new ComponentName(getActivity(), SampleJobService.class));

İş hizmetini senkronize etmek için requestImmediateSync yöntemini kullanın. Kullanıcının senkronizasyonun tamamlanmasını beklemesi gerektiğinden, istek sürenizi nispeten kısa tutmalısınız.

İş hizmetinin kanal ve program verilerini arka planda düzenli olarak senkronize etmesi için setUpPeriodicSync yöntemini kullanın:

Kotlin

EpgSyncJobService.setUpPeriodicSync(
        context,
        inputId,
        ComponentName(context, SampleJobService::class.java)
)

Java

EpgSyncJobService.setUpPeriodicSync(context, inputId,
        new ComponentName(context, SampleJobService.class));

TIF Companion Library, requestImmediateSync için ek bir aşırı yüklenmiş yöntem sağlar. Bu yöntem, senkronize edilecek kanal verilerinin süresini milisaniye cinsinden belirtmenize olanak tanır. Varsayılan yöntem, bir saatlik kanal verisini senkronize eder.

TIF Companion Library, senkronize edilecek kanal verilerinin süresini ve düzenli senkronizasyonun ne sıklıkta gerçekleşeceğini belirtmenize olanak tanıyan ek bir aşırı yüklenmiş setUpPeriodicSync yöntemi de sağlar. Varsayılan yöntem, her 12 saatte bir 48 saatlik kanal verisini senkronize eder.

Kanal verileri ve EPG hakkında daha fazla bilgi için Kanal verileriyle çalışma başlıklı makaleyi inceleyin.

Ayarlama isteklerini ve medya oynatımını yönetin.

Kullanıcı belirli bir kanalı seçtiğinde, sistem TV uygulaması, uygulamanız tarafından oluşturulan bir Session kullanarak istenen kanala geçiş yapar ve içeriği oynatır. TIF Companion Library, sistemden gelen kanal ve oturum çağrılarını işlemek için genişletebileceğiniz çeşitli sınıflar sağlar.

BaseTvInputService alt sınıfınız, ayarlama isteklerini işleyen oturumlar oluşturur. onCreateSession yöntemini geçersiz kılın, BaseTvInputService.Session sınıfından genişletilmiş bir oturum oluşturun ve yeni oturumunuzla super.sessionCreated yöntemini çağırın. Aşağıdaki örnekte, onCreateSession BaseTvInputService.Session sınıfını genişleten bir RichTvInputSessionImpl nesnesi döndürür:

Kotlin

override fun onCreateSession(inputId: String): Session =
        RichTvInputSessionImpl(this, inputId).apply {
            setOverlayViewEnabled(true)
        }

Java

@Override
public final Session onCreateSession(String inputId) {
    RichTvInputSessionImpl session = new RichTvInputSessionImpl(this, inputId);
    session.setOverlayViewEnabled(true);
    return session;
}

Kullanıcı, kanallarınızdan birini görüntülemeye başlamak için sistem TV uygulamasını kullandığında sistem, oturumunuzun onPlayChannel yöntemini çağırır. Program oynatılmaya başlamadan önce özel kanal başlatma işlemleri yapmanız gerekiyorsa bu yöntemi geçersiz kılın.

Sistem daha sonra şu anda planlanmış programı alır ve oturumunuzun onPlayProgram yöntemini çağırarak program bilgilerini ve başlangıç zamanını milisaniye cinsinden belirtir. Programı oynatmaya başlamak için TvPlayer arayüzünü kullanın.

Medya oynatıcı kodunuz, belirli oynatma etkinliklerini işlemek için TvPlayer işlevini uygulamalıdır. TvPlayer sınıfı, BaseTvInputService uygulamanıza karmaşıklık katmadan zaman kaydırma kontrolleri gibi özellikleri işler.

Oturumunuzun getTvPlayer yönteminde, TvPlayer arayüzünü uygulayan medya oynatıcınızı döndürün. TV Giriş Hizmeti örnek uygulamasında, ExoPlayer'ı kullanan bir medya oynatıcı uygulanır.

TV giriş çerçevesini kullanarak bir TV giriş hizmeti oluşturun.

Eğer TV giriş servisiniz TIF Companion Library'yi kullanamıyorsa, aşağıdaki bileşenleri uygulamanız gerekmektedir:

  • TvInputService, TV girişi için uzun süreli ve arka planda kullanılabilirlik sağlar.
  • TvInputService.Session TV giriş durumunu korur ve ana uygulama ile iletişim kurar.
  • TvContract TV girişine erişilebilen kanalları ve programları tanımlar.
  • TvContract.Channels, TV kanalıyla ilgili bilgileri gösterir.
  • TvContract.Programs, program başlığı ve başlangıç saati gibi verilerle bir TV programını açıklar.
  • TvTrackInfo bir ses, video veya altyazı parçasını temsil eder.
  • TvContentRating bir içerik derecelendirmesini tanımlar ve özel içerik derecelendirme şemalarına olanak tanır.
  • TvInputManager, sistem TV uygulaması için bir API sağlar ve TV girişleri ile uygulamalarla etkileşimi yönetir.

Ayrıca şunları da yapmanız gerekir:

  1. TV giriş hizmetinizi manifest dosyasında Manifest dosyasında TV giriş hizmetinizi bildirin bölümünde açıklandığı gibi tanımlayın.
  2. Hizmet meta verileri dosyasını oluşturun.
  3. Kanal ve program bilgilerinizi oluşturup kaydedin.
  4. Kurulum etkinliğinizi oluşturun.

TV giriş hizmetinizi tanımlama

Hizmetiniz için TvInputService sınıfını genişletirsiniz. TvInputService uygulaması, sisteme ait hizmetin kendisine bağlandığı bir bağlı hizmettir. Uygulamanız gereken hizmet yaşam döngüsü yöntemleri Şekil 1'de gösterilmiştir.

onCreate yöntemi, sistem tarafından yönlendirilen işlemleri işlemek için kullanıcı arayüzü iş parçacığından ayrı bir işlem iş parçacığı sağlayan HandlerThread öğesini başlatır. Aşağıdaki örnekte, onCreate yöntemi CaptioningManager öğesini başlatır ve ACTION_BLOCKED_RATINGS_CHANGED ile ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED işlemlerini işlemeye hazırlanır. Bu eylemler, kullanıcının ebeveyn denetimi ayarlarını değiştirmesi ve engellenen derecelendirmeler listesinde bir değişiklik olması durumunda tetiklenen sistem amaçlarını tanımlar.

Kotlin

override fun onCreate() {
    super.onCreate()
    handlerThread = HandlerThread(javaClass.simpleName).apply {
        start()
    }
    dbHandler = Handler(handlerThread.looper)
    handler = Handler()
    captioningManager = getSystemService(Context.CAPTIONING_SERVICE) as CaptioningManager

    setTheme(android.R.style.Theme_Holo_Light_NoActionBar)

    sessions = mutableListOf<BaseTvInputSessionImpl>()
    val intentFilter = IntentFilter().apply {
        addAction(TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED)
        addAction(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED)
    }
    registerReceiver(broadcastReceiver, intentFilter)
}

Java

@Override
public void onCreate() {
    super.onCreate();
    handlerThread = new HandlerThread(getClass()
      .getSimpleName());
    handlerThread.start();
    dbHandler = new Handler(handlerThread.getLooper());
    handler = new Handler();
    captioningManager = (CaptioningManager)
      getSystemService(Context.CAPTIONING_SERVICE);

    setTheme(android.R.style.Theme_Holo_Light_NoActionBar);

    sessions = new ArrayList<BaseTvInputSessionImpl>();
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(TvInputManager
      .ACTION_BLOCKED_RATINGS_CHANGED);
    intentFilter.addAction(TvInputManager
      .ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED);
    registerReceiver(broadcastReceiver, intentFilter);
}

Şekil 1. TvInputService yaşam döngüsü.

Engellenen içeriklerle çalışma ve ebeveyn denetimi sağlama hakkında daha fazla bilgi için İçeriği kontrol etme başlıklı makaleyi inceleyin. TV giriş servisinizde ele almak isteyebileceğiniz daha fazla sistem odaklı işlem için TvInputManager'a bakın.

TvInputService, oynatıcı durumu değişikliklerini işlemek için Handler.Callback uygulayan bir TvInputService.Session oluşturur. onSetSurface ile TvInputService.Session, Surface'yi video içeriğiyle ayarlar. Videoyu oluşturmak için Surface ile çalışma hakkında daha fazla bilgi edinmek için Oynatıcıyı yüzeyle entegre etme başlıklı makaleyi inceleyin.

TvInputService.Session, kullanıcı bir kanal seçtiğinde onTune etkinliğini işler ve içerik ile içerik meta verilerindeki değişiklikler için sistem TV uygulamasını bilgilendirir. Bu notify yöntemler, bu eğitimin ilerleyen bölümlerinde İçeriği kontrol etme ve Parça seçimini yönetme başlıkları altında daha ayrıntılı olarak açıklanmıştır.

Kurulum etkinliğinizi tanımlama

Sistem TV uygulaması, TV girişiniz için tanımladığınız kurulum etkinliğiyle çalışır. Kurulum etkinliği gereklidir ve sistem veritabanı için en az bir kanal kaydı sağlamalıdır. Sistem TV uygulaması, TV girişi için bir kanal bulamadığında kurulum etkinliğini başlatır.

Kurulum etkinliği, TV girişinden kullanılabilen kanalları sistem TV uygulamasına açıklar. Bu durum, bir sonraki derste (Kanal verileri oluşturma ve güncelleme) gösterilmektedir.

Ek referanslar