Kanal verileriyle çalışma

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:

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:

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.

  1. Kanal numarası (COLUMN_DISPLAY_NUMBER)
  2. Simge (android:icon TV girişinin manifest dosyası)
  3. Program açıklaması (COLUMN_SHORT_DESCRIPTION)
  4. Program başlığı (COLUMN_TITLE)
  5. Kanal logosu (TvContract.Channels.Logo)
    • Çevresindeki metinle eşleştirmek için #EEEEEE rengini kullanın
    • Dolgu ekleme
  6. Poster resmi (COLUMN_POSTER_ART_URI)
    • 16:9 ile 4:3 arasındaki en boy oranı

Şekil 1. Sistem TV uygulaması kanalı ve program bilgileri sunucusu.

Sistem TV uygulaması, program rehberinde aynı bilgileri (poster resmi dahil) sunar. Şekil 2'de gösterildiği gibidir.

Şekil 2. Sistem TV uygulaması program rehberi.

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.

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ü.

Şekil 1. Örnek uygulama bağlantısı kanal içeriği gösterilirken Kanallar satırında görüntülenir.

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.

Şekil 2. Uygulama bağlantısı ayrıntıları.

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), sistem ACTION_MAIN kullanıyor CATEGORY_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.