TV girişiniz en az şu kadar süre için Elektronik Program Rehberi (EPG) verisi sağlamalıdır: tek kanalda daha fazla video görürsünüz. Ayrıca bu bilgileri belirli aralıklarla güncellemenin boyutu ve işleme iş parçacığı dikkate alınarak bir proje yöneticisisiniz. Ayrıca kanallar için uygulama bağlantıları da sağlayabilirsiniz. içeriğe ve etkinliklere yönlendiren reklam öğeleri içerir. Bu derste, sistem veritabanını oluşturmayı da gerektirir.
Şunu deneyin: TV Giriş Hizmeti örnek uygulaması.
İzin al
TV girişinizin EPG verileriyle çalışması için Android manifest dosyasında yazma izninin olmasını sağlayın:
<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. Kurulumunuzda
kanal verilerinizi aşağıdaki alanlarla eşlemeniz gerekir:
TvContract.Channels
sınıf:
COLUMN_DISPLAY_NAME
- kanalCOLUMN_DISPLAY_NUMBER
- gösterilen kanal numaraCOLUMN_INPUT_ID
- TV giriş hizmetinin kimliğiCOLUMN_SERVICE_TYPE
- kanalın hizmet türüCOLUMN_TYPE
- kanalın yayın standardı türCOLUMN_VIDEO_FORMAT
- varsayılan video biçimi kanal için
TV giriş çerçevesi hem geleneksel yayın hem de iletişim için yeterince genel olsa da over-the-top (OTT) içeriğini herhangi bir ayrım olmaksızın, aşağıdaki sütunları yukarıdakilere ek olarak, geleneksel yayın kanallarını daha iyi tanımlamak için kullanın:
COLUMN_ORIGINAL_NETWORK_ID
- televizyon ağ kimliğiCOLUMN_SERVICE_ID
- hizmet kimliğiCOLUMN_TRANSPORT_STREAM_ID
- taşıma akışı Kimlik
Kanallarınız için uygulama bağlantısı bilgilerini sağlamak istiyorsanız bazı ek alanları güncelleyebilirsiniz. Uygulama bağlantısı alanları hakkında daha fazla bilgi için Uygulama bağlantısı bilgilerini ekleyin.
İnternet yayını tabanlı TV girişleri için yukarıdaki değerlere kendi değerlerinizi atayın. Böylece, her kanal benzersiz bir şekilde tanımlanabilir.
Arka uç sunucunuzdan ve kurulumunuzdan kanal meta verilerinizi (XML, JSON vb.) alın etkinliği, değerleri sistem veritabanıyla şu şekilde eşler:
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);
Yukarıdaki örnekte channel
,
arka uç sunucusuna gidin.
Kanal ve program bilgilerini sunma
Sistem TV uygulaması, kanallar arasında gezinen kullanıcılara kanal ve program bilgilerini sunar. Şekil 1'de gösterildiği gibidir. Kanal ve program bilgilerinin sistem TV uygulamasının lütfen aşağıdaki yönergeleri izleyin.
- Kanal numarası (
COLUMN_DISPLAY_NUMBER
) - Simge
(
android:icon
TV girişinin manifest dosyası) - Program açıklaması (
COLUMN_SHORT_DESCRIPTION
) - Program başlığı (
COLUMN_TITLE
) - Kanal logosu (
TvContract.Channels.Logo
)- Çevresindeki metinle eşleştirmek için #EEEEEE rengini kullanın
- Dolgu ekleme
- Poster resmi (
COLUMN_POSTER_ART_URI
)- 16:9 ile 4:3 arasındaki en boy oranı
Sistem TV uygulaması, program rehberinde aynı bilgileri (poster resmi dahil) sunar. Şekil 2'de gösterildiği gibidir.
Kanal verilerini güncelleme
Mevcut kanal verilerini güncellerken
update()
.
yöntemini kullanmanızı öneririz. Verilerin mevcut sürümünü belirleyebilirsiniz.
Channels.COLUMN_VERSION_NUMBER
kullanılarak
ve Programs.COLUMN_VERSION_NUMBER
.
Not: Kanal verileri ContentProvider
dosyasına ekleniyor
zaman alabilir. Mevcut programları (o anki saatten iki saat öncesine kadar) ekleme
yalnızca EpgSyncJobService
cihazınızı, diğerlerini de güncelleyecek şekilde yapılandırdığınızda
arka planda oynatma listesidir. Görüntüleyin
Örnek olarak Android TV Canlı TV Örnek Uygulaması'nı inceleyebilirsiniz.
Kanal verilerini toplu yükleme
Sistem veritabanını büyük miktarda kanal verileriyle güncellerken ContentResolver
kullanın.
applyBatch()
veya
bulkInsert()
yöntemidir. 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şleyin
Sunucudan bir akış getirmek veya veritabanına erişmek gibi veri manipülasyonları,
UI iş parçacığını engellemez. AsyncTask
kullanımı
yöntemini kullanarak güncellemeleri eşzamansız olarak gerçekleştirebilirsiniz. Örneğin, arka uç sunucusundan kanal bilgilerini yüklerken
AsyncTask
öğesini aşağıdaki şekilde 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
WorkManager
güncelleme işlemini boşta kaldığında (ör.her gün saat 03:00'te) çalıştır.
Veri güncelleme görevlerini UI iş parçacığından ayırmak için kullanılan diğer teknikler arasında
HandlerThread
sınıf veya Looper
kullanarak kendi sınıfınızı uygulayabilirsiniz
ve Handler
sınıf. Bkz.
İşlemler ve ileti dizileri başlıklı makaleye göz atın.
Uygulama bağlantısı bilgilerini ekleme
Kanallar, kullanıcıların alakalı bir uygulamayı kolayca başlatabilmesi için uygulama bağlantılarını kullanabilir gerçekleştirdikleri etkinliklerden en iyi şekilde yararlanabilirler. Kanal uygulamaları gösteren etkinlikler başlatarak kullanıcı etkileşimini artıran uygulama bağlantıları veya ek içerik sunmaz. Örneğin, uygulama bağlantıları şunları yapabilirsiniz:
- Kullanıcıyı ilgili içeriği keşfetmesi ve satın alması için yönlendirin.
- Şu anda oynatılan içerik hakkında ek bilgi sağlayın.
- Bölümlerden oluşan içerikleri görüntülerken sonraki bölümü şurada izlemeye başlayın: seri.
- Kullanıcının içerikle etkileşim kurmasına olanak tanıma (ör. puan verme veya yorum yapma) içeriklerinize ekleyebilirsiniz.
Kullanıcı Seç'e basarak uygulama bağlantıları Kanal içeriğini izlerken TV menüsü.
Kullanıcı uygulama bağlantısını seçtiğinde, sistem şunu kullanarak bir etkinlik başlatır: kanal uygulaması tarafından belirtilen bir intent URI'si. Kanal içeriği oynatılmaya devam ediyor uygulama bağlantısı etkinliği etkin durumdayken. Kullanıcı kanala geri dönebilir Geri düğmesine basarak içeriği.
Uygulama bağlantısı kanalı verilerini sağlama
Android TV her kanal için otomatik olarak bir uygulama bağlantısı oluşturur.
kanal verilerinden gelen
bilgileri kullanarak. Uygulama bağlantısı bilgilerini sağlamak için:
aşağıdaki ayrıntıları belirtmeniz
TvContract.Channels
alan:
COLUMN_APP_LINK_COLOR
- bu kanalın 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ının uygulama rozeti simgesinin URI'si. Örneğin, örnek uygulama rozeti simgesi, Ş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'yı oluşturabilirsiniz.toUri(int)
şununla kullanılıyor:URI_INTENT_SCHEME
ve URI'yı şu şekilde orijinal amaca geri dönüştür:parseUri()
.COLUMN_APP_LINK_POSTER_ART_URI
. - Uygulama bağlantısının arka planı olarak kullanılan poster resminin URI'sı bu kanal için geçerli. Örnek poster resmi için Şekil 2, açıklama metni 1'e bakın.COLUMN_APP_LINK_TEXT
- Bu kanalın uygulama bağlantısının açıklayıcı bağlantı metni. Örneğin, uygulama bağlantısı açıklaması, Şekil 2, açıklama metni 3'teki metne bakın.
Kanal verilerinde uygulama bağlantısı bilgileri belirtilmiyorsa sistem bir varsayılan uygulama bağlantısı oluşturur. Sistem, varsayılan ayrıntıları aşağıdaki şekilde seçer:
- Intent URI'si için
(
COLUMN_APP_LINK_INTENT_URI
), sistemACTION_MAIN
kullanıyorCATEGORY_LEANBACK_LAUNCHER
kategorisi için etkinlik. Bu etkinlik tanımlanmamışsa, çalışmayan bir uygulama bağlantısı görüntülenir. kullanıcı tıkladığında hiçbir şey olmaz. - Açıklayıcı metin için
(
COLUMN_APP_LINK_TEXT
), sistem "app-name uygulamasını aç" seçeneğini kullanır. Uygun bir uygulama bağlantısı amaç URI'si tanımlanmamışsa sistem "Kullanılabilir bağlantı yok" ifadesini kullanır. - Vurgu rengi için
(
COLUMN_APP_LINK_COLOR
), sistem varsayılan uygulama rengini kullanır. - Poster resmi için
(
COLUMN_APP_LINK_POSTER_ART_URI
), Sistem, uygulamanın ana ekran banner'ını kullanır. Uygulama size bir sistem varsayılan bir TV uygulaması resmi kullanır. - Rozet simgesi için
(
COLUMN_APP_LINK_ICON_URI
), sistem, uygulama adını gösteren bir rozet kullanır. Sistem, uygulama banner'ı veya poster resmi için varsayılan uygulama resmi varsa uygulama rozeti gösterilmez.
Kanallarınızın uygulama bağlantısı ayrıntılarını, uygulamanızın
kurulum etkinliği. Bu uygulama bağlantısı ayrıntılarını istediğiniz zaman güncelleyebilirsiniz.
Uygulama bağlantısının kanal değişiklikleriyle eşleşmesi gerekiyorsa uygulamayı güncelleyin
bağlantı ayrıntıları ve arama
Gerektiğinde ContentResolver.update()
. Güncelleme hakkında daha fazla bilgi için
kanal verilerini inceleyin. Kanal verilerini güncelleme bölümünü inceleyin.