TV girişiniz, kurulum etkinliğinde en az bir kanal için Elektronik Program Rehberi (EPG) verileri sağlamalıdır. Ayrıca, güncellemenin boyutu ve bunu işleyen işleme iş parçacığı dikkate alınarak bu verileri düzenli olarak güncellemeniz gerekir. Ayrıca, kullanıcıyı ilgili içeriklere ve etkinliklere yönlendiren kanallar için uygulama bağlantıları da sağlayabilirsiniz. Bu derste, sistem veritabanında kanal ve program verilerinin oluşturulması ve güncellenmesiyle ilgili bilgiler verilmektedir.
TV Giriş Hizmeti örnek uygulamasını deneyin.
İzin alma
TV girişinizin EPG verileriyle çalışması için Android manifest dosyasında yazma iznini aşağıdaki şekilde tanımlaması gerekir:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
Kanalları veritabanına kaydetme
Android TV sistem veritabanı, TV girişleri için kanal verilerinin kayıtlarını tutar. Kurulum etkinliğinizde, her kanalınız için kanal verilerinizi TvContract.Channels sınıfının aşağıdaki alanlarıyla eşlemeniz gerekir:
COLUMN_DISPLAY_NAME- Kanalın görünen adıCOLUMN_DISPLAY_NUMBER- Gösterilen kanal numarasıCOLUMN_INPUT_ID: TV giriş hizmetinin kimliğiCOLUMN_SERVICE_TYPE: Kanalın hizmet türüCOLUMN_TYPE: Kanalın yayın standardı türüCOLUMN_VIDEO_FORMAT: Kanalın varsayılan video biçimi
TV girişi çerçevesi, geleneksel yayınları ve internet üzerinden yayınlanan (OTT) içerikleri herhangi bir ayrım yapmadan işleyecek kadar genel olsa da geleneksel yayın kanallarını daha iyi tanımlamak için aşağıdaki sütunları da tanımlamak isteyebilirsiniz:
COLUMN_ORIGINAL_NETWORK_ID- televizyon ağı kimliğiCOLUMN_SERVICE_ID- hizmet kimliğiCOLUMN_TRANSPORT_STREAM_ID- the transport stream ID
Kanallarınız için uygulama bağlantısı ayrıntıları sağlamak istiyorsanız bazı ek alanları güncellemeniz gerekir. Uygulama bağlantısı alanları hakkında daha fazla bilgi için Uygulama bağlantısı bilgileri ekleme başlıklı makaleyi inceleyin.
İnternet üzerinden yayınlanan TV girişleri için her kanalın benzersiz şekilde tanımlanabilmesi amacıyla kendi değerlerinizi buna göre atayın.
Kanal meta verilerinizi (XML, JSON veya başka bir biçimde) arka uç sunucunuzdan çekin ve kurulum etkinliğinizde değerleri sistem veritabanıyla aşağıdaki gibi eşleyin:
Kotlin
val values = ContentValues().apply { put(TvContract.Channels.COLUMN_DISPLAY_NUMBER, channel.number) put(TvContract.Channels.COLUMN_DISPLAY_NAME, channel.name) put(TvContract.Channels.COLUMN_ORIGINAL_NETWORK_ID, channel.originalNetworkId) put(TvContract.Channels.COLUMN_TRANSPORT_STREAM_ID, channel.transportStreamId) put(TvContract.Channels.COLUMN_SERVICE_ID, channel.serviceId) put(TvContract.Channels.COLUMN_VIDEO_FORMAT, channel.videoFormat) } val uri = context.contentResolver.insert(TvContract.Channels.CONTENT_URI, values)
Java
ContentValues values = new ContentValues(); values.put(Channels.COLUMN_DISPLAY_NUMBER, channel.number); values.put(Channels.COLUMN_DISPLAY_NAME, channel.name); values.put(Channels.COLUMN_ORIGINAL_NETWORK_ID, channel.originalNetworkId); values.put(Channels.COLUMN_TRANSPORT_STREAM_ID, channel.transportStreamId); values.put(Channels.COLUMN_SERVICE_ID, channel.serviceId); values.put(Channels.COLUMN_VIDEO_FORMAT, channel.videoFormat); Uri uri = context.getContentResolver().insert(TvContract.Channels.CONTENT_URI, values);
Bu örnekte channel, arka uç sunucusundan gelen kanal meta verilerini içeren bir nesnedir.
Mevcut kanal ve program bilgileri
Sistem TV uygulaması, kullanıcılar kanallar arasında geçiş yaparken kanal ve program bilgilerini Şekil 1'de gösterildiği gibi sunar. Kanal ve program bilgilerinin, sistem TV uygulamasının kanal ve program bilgileri sunucusuyla çalıştığından emin olmak için aşağıdaki yönergeleri uygulayın:
- Kanal numarası (
COLUMN_DISPLAY_NUMBER) - Simge
(TV girişinin manifest dosyasında
android:icon) - Program açıklaması (
COLUMN_SHORT_DESCRIPTION) - Program başlığı (
COLUMN_TITLE) - Kanal logosu (
TvContract.Channels.Logo)- Çevredeki metinle eşleşmesi için #EEEEEE rengini kullanın
- Dolgu malzemesi eklemeyin.
- Poster resmi (
COLUMN_POSTER_ART_URI) - 16:9 ile 4:3 arasında en-boy oranı
Şekil 2'de gösterildiği gibi, sistem TV uygulaması, program rehberi aracılığıyla poster resmi de dahil olmak üzere aynı bilgileri sağlar.
Kanal verilerini güncelleme
Mevcut kanal verilerini güncellerken verileri silip yeniden eklemek yerine update yöntemini kullanın. Güncellenecek kayıtları seçerken Channels.COLUMN_VERSION_NUMBER ve Programs.COLUMN_VERSION_NUMBER kullanarak verilerin mevcut sürümünü belirleyebilirsiniz.
Not: Kanal verilerinin ContentProvider'ye eklenmesi zaman alabilir. Yalnızca EpgSyncJobService öğenizi, kanal verilerinin geri kalanını arka planda güncelleyecek şekilde yapılandırdığınızda mevcut programları (mevcut saatten iki saat öncesine kadar olanlar) ekleyin. Örnek için
Android TV'de Canlı TV Örnek Uygulaması'na bakın.
Kanal verilerini toplu yükleme
Sistem veritabanını büyük miktarda kanal verisiyle güncellerken ContentResolver
applyBatch veya bulkInsert yöntemini kullanın. applyBatch kullanan bir örneği aşağıda bulabilirsiniz:
Kotlin
val ops = ArrayList<ContentProviderOperation>() val programsCount = channelInfo.mPrograms.size channelInfo.mPrograms.forEachIndexed { index, program -> ops += ContentProviderOperation.newInsert( TvContract.Programs.CONTENT_URI).run { withValues(programs[index]) withValue(TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS, programStartSec * 1000) withValue( TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS, (programStartSec + program.durationSec) * 1000 ) build() } programStartSec += program.durationSec if (index % 100 == 99 || index == programsCount - 1) { try { contentResolver.applyBatch(TvContract.AUTHORITY, ops) } catch (e: RemoteException) { Log.e(TAG, "Failed to insert programs.", e) return } catch (e: OperationApplicationException) { Log.e(TAG, "Failed to insert programs.", e) return } ops.clear() } }
Java
ArrayList<ContentProviderOperation> ops = new ArrayList<>(); int programsCount = channelInfo.mPrograms.size(); for (int j = 0; j < programsCount; ++j) { ProgramInfo program = channelInfo.mPrograms.get(j); ops.add(ContentProviderOperation.newInsert( TvContract.Programs.CONTENT_URI) .withValues(programs.get(j)) .withValue(Programs.COLUMN_START_TIME_UTC_MILLIS, programStartSec * 1000) .withValue(Programs.COLUMN_END_TIME_UTC_MILLIS, (programStartSec + program.durationSec) * 1000) .build()); programStartSec = programStartSec + program.durationSec; if (j % 100 == 99 || j == programsCount - 1) { try { getContentResolver().applyBatch(TvContract.AUTHORITY, ops); } catch (RemoteException | OperationApplicationException e) { Log.e(TAG, "Failed to insert programs.", e); return; } ops.clear(); } }
Kanal verilerini eşzamansız olarak işleme
Sunucudan veri akışı alma veya veritabanına erişme gibi veri manipülasyonu işlemleri, kullanıcı arayüzü iş parçacığını engellememelidir. Güncellemeleri eşzamansız olarak gerçekleştirmek için AsyncTask kullanabilirsiniz. Örneğin, arka uç sunucusundan kanal bilgileri yüklerken AsyncTask öğesini aşağıdaki gibi kullanabilirsiniz:
Kotlin
private class LoadTvInputTask(val context: Context) : AsyncTask<Uri, Unit, Unit>() { override fun doInBackground(vararg uris: Uri) { try { fetchUri(uris[0]) } catch (e: IOException) { Log.d("LoadTvInputTask", "fetchUri error") } } @Throws(IOException::class) private fun fetchUri(videoUri: Uri) { context.contentResolver.openInputStream(videoUri).use { inputStream -> Xml.newPullParser().also { parser -> try { parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false) parser.setInput(inputStream, null) sTvInput = ChannelXMLParser.parseTvInput(parser) sSampleChannels = ChannelXMLParser.parseChannelXML(parser) } catch (e: XmlPullParserException) { e.printStackTrace() } } } } }
Java
private static class LoadTvInputTask extends AsyncTask<Uri, Void, Void> { private Context mContext; public LoadTvInputTask(Context context) { mContext = context; } @Override protected Void doInBackground(Uri... uris) { try { fetchUri(uris[0]); } catch (IOException e) { Log.d("LoadTvInputTask", "fetchUri error"); } return null; } private void fetchUri(Uri videoUri) throws IOException { InputStream inputStream = null; try { inputStream = mContext.getContentResolver().openInputStream(videoUri); XmlPullParser parser = Xml.newPullParser(); try { parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); parser.setInput(inputStream, null); sTvInput = ChannelXMLParser.parseTvInput(parser); sSampleChannels = ChannelXMLParser.parseChannelXML(parser); } catch (XmlPullParserException e) { e.printStackTrace(); } } finally { if (inputStream != null) { inputStream.close(); } } } }
EPG verilerini düzenli olarak güncellemeniz gerekiyorsa, aşağıdaki yöntemi kullanmayı düşünün.WorkManager Güncelleme işlemini, örneğin her gün sabah 3:00'te olduğu gibi, boş zamanlarda çalıştırmak.
Veri güncelleme görevlerini kullanıcı arayüzü iş parçacığından ayırmak için HandlerThread sınıfını kullanabilirsiniz. Alternatif olarak, Looper ve Handler sınıflarını kullanarak kendi çözümünüzü de uygulayabilirsiniz. Daha fazla bilgi için
İşlemler ve iş parçacıkları başlıklı makaleyi inceleyin.
Uygulama bağlantısı bilgileri ekleme
Kanallar, kullanıcıların kanal içeriğini izlerken ilgili bir etkinliği başlatmasına olanak tanımak için uygulama bağlantılarını kullanabilir. Kanal uygulamaları, ilgili bilgileri veya ek içerikleri gösteren etkinlikler başlatarak kullanıcı etkileşimini artırmak için uygulama bağlantılarını kullanır. Örneğin, uygulama bağlantılarını aşağıdaki amaçlarla kullanabilirsiniz:
- Kullanıcıyı ilgili içerikleri keşfetmeye ve satın almaya yönlendirin.
- Oynatılmakta olan içerikle ilgili ek bilgiler sağlayın.
- Bölümler halinde yayınlanan içerikleri izlerken, dizinin bir sonraki bölümünü izlemeye başlayın.
- Kullanıcının içerikle etkileşim kurmasına (örneğin, içeriği değerlendirmesine veya yorumlamasına) olanak tanıyın, ancak içerik oynatımını kesintiye uğratmayın.
Kullanıcı, kanal içeriğini izlerken TV menüsünü göstermek için Seç'e bastığında uygulama bağlantıları gösterilir.
Şekil 1. Kanal içeriği gösterilirken Kanallar satırında gösterilen örnek bir uygulama bağlantısı.
Kullanıcı uygulama bağlantısını seçtiğinde sistem, kanal uygulaması tarafından belirtilen bir intent URI'si kullanarak bir etkinlik başlatır. Uygulama bağlantısı etkinliği devam ederken kanal içeriği oynatılmaya devam eder. Kullanıcı, Geri'ye basarak kanal içeriğine dönebilir.
Uygulama bağlantısı kanal verilerini sağlama
Android TV, kanal verilerinden aldığı bilgileri kullanarak her kanal için otomatik olarak bir uygulama bağlantısı oluşturur. Uygulama bağlantısı bilgilerini sağlamak için, TvContract.Channels alanlarınızda aşağıdaki ayrıntıları belirtin:
COLUMN_APP_LINK_COLOR- Bu kanal için uygulama bağlantısının vurgu rengi. Örnek bir vurgu rengi için Şekil 2, açıklama metni 3'e bakın.COLUMN_APP_LINK_ICON_URI- Bu kanalın uygulama bağlantısına ait uygulama rozeti simgesinin URI'si. Örnek uygulama rozeti simgesi için şekil 2, açıklama metni 2'ye bakın.COLUMN_APP_LINK_INTENT_URI- Bu kanal için uygulama bağlantısının intent URI'si. URI'yitoUri(int)ileURI_INTENT_SCHEMEkullanarak oluşturabilir veparseUriile URI'yi orijinal amaca geri dönüştürebilirsiniz.COLUMN_APP_LINK_POSTER_ART_URI- Bu kanalın uygulama bağlantısının arka planı olarak kullanılan poster resminin URI'si. Örnek poster resmi için Şekil 2, açıklama metni 1'e bakın.COLUMN_APP_LINK_TEXT: Bu kanal için uygulama bağlantısının açıklayıcı bağlantı metni. Örnek bir uygulama bağlantısı açıklaması için Şekil 2'deki 3 numaralı açıklama metnine bakın.
Kanal verilerinde uygulama bağlantısı bilgileri belirtilmemişse sistem varsayılan bir uygulama bağlantısı oluşturur. Sistem, varsayılan ayrıntıları aşağıdaki şekilde seçer:
- Amaç URI'si (
COLUMN_APP_LINK_INTENT_URI) için sistem, genellikle uygulama manifestinde tanımlananCATEGORY_LEANBACK_LAUNCHERkategorisi içinACTION_MAINetkinliğini kullanır. Bu etkinlik tanımlanmazsa çalışmayan bir uygulama bağlantısı gösterilir. Kullanıcı bu bağlantıyı tıkladığında hiçbir şey olmaz. - Açıklayıcı metin için (
COLUMN_APP_LINK_TEXT) sistem "app-name uygulamasını aç" ifadesini kullanır. Geçerli bir uygulama bağlantısı amaç URI'si tanımlanmamışsa sistem "Bağlantı yok" ifadesini kullanır. - Vurgu rengi (
COLUMN_APP_LINK_COLOR) için sistem, varsayılan uygulama rengini kullanır. - Sistem, poster resmi (
COLUMN_APP_LINK_POSTER_ART_URI) için uygulamanın ana ekran banner'ını kullanır. Uygulama banner sağlamıyorsa sistem varsayılan bir TV uygulaması resmi kullanır. - Rozet simgesi (
COLUMN_APP_LINK_ICON_URI) için sistem, uygulama adını gösteren bir rozet kullanır. Sistem, poster resmi için uygulama banner'ını veya varsayılan uygulama resmini de kullanıyorsa uygulama rozeti gösterilmez.
Kanallarınız için uygulama bağlantısı ayrıntılarını uygulamanızın kurulum etkinliğinde belirtirsiniz. Bu uygulama bağlantısı ayrıntılarını istediğiniz zaman güncelleyebilirsiniz. Bu nedenle, bir uygulama bağlantısının kanal değişiklikleriyle eşleşmesi gerekiyorsa uygulama bağlantısı ayrıntılarını güncelleyin ve gerektiğinde ContentResolver.update işlevini çağırın. Kanal verilerini güncelleme hakkında daha fazla bilgi için Kanal verilerini güncelleme başlıklı makaleyi inceleyin.