Android TV, Android arama arayüzünü kullanır yüklü uygulamalardan içerik verilerini almak ve arama sonuçlarını kullanıcıya yayınlamak için kullanılır. Uygulamanızın içerik verileri, kullanıcının içeriğe anında erişmesini sağlamak için bu sonuçlara dahil edilebilir en iyi şekilde yararlanabilirsiniz.
Uygulamanız, Android TV'ye Android TV'nin önerilen aramayı oluşturabileceği veri alanlarını sağlamalıdır
sonuçları gösterilir. Bunu yapmak için uygulamanızın
İçerik sunan İçerik Sağlayıcı
bir
searchable.xml
yapılandırma dosyası, içeriği açıklayan
sağlayıcı ve Android TV için diğer önemli bilgileri sağlar. Ayrıca
kullanıcı önerilen bir arama sonucunu seçtiğinde tetiklenen amaç Örneğin,
daha fazla bilgi için Ekle
özel arama önerileri. Bu kılavuzda, Android TV uygulamalarına özgü ana noktalar ele alınmaktadır.
Bu kılavuzu okumadan önce, şurada açıklanan kavramları bildiğinizden emin olun: Search API'si kılavuzu. Ayrıca, Arama işlevi ekleme makalesini inceleyin.
Bu kılavuzdaki örnek kod, Leanback örnek uygulaması ,
Sütunları tanımlama
SearchManager
, beklediği veri alanlarını
sütunlarının arasında yer alır. Verilerinizin biçiminden bağımsız olarak, veri alanlarınızı
bu sütunlar genellikle içerik verilerinize erişen sınıfta yer alır. Uygulama geliştirme hakkında
ihtiyaç duyulan alanlarla eşleyen bir sınıf oluşturmak için
Öneri tablosu oluşturma.
SearchManager
sınıfı, Android TV için birkaç sütun içerir. Bazı
daha önemli sütunlar aşağıdaki tabloda açıklanmıştır.
Değer | Açıklama |
---|---|
SUGGEST_COLUMN_TEXT_1 |
İçeriğinizin adı (zorunlu) |
SUGGEST_COLUMN_TEXT_2 |
İçeriğinizin metin açıklaması |
SUGGEST_COLUMN_RESULT_CARD_IMAGE |
İçeriğiniz için bir resim, poster veya kapak |
SUGGEST_COLUMN_CONTENT_TYPE |
Medyanızın MIME türü |
SUGGEST_COLUMN_VIDEO_WIDTH |
Medyanızın çözünürlük genişliği |
SUGGEST_COLUMN_VIDEO_HEIGHT |
Medyanızın çözünürlük yüksekliği |
SUGGEST_COLUMN_PRODUCTION_YEAR |
İçeriğinizin üretim yılı (zorunlu) |
SUGGEST_COLUMN_DURATION |
Medyanızın milisaniye cinsinden süresi (gerekli) |
Arama çerçevesi için aşağıdaki sütunlar gereklidir:
İçeriğinize ait bu sütunların değerleri, diğer sütunlardaki aynı içeriğin değerleriyle eşleştiğinde tarafından bulunan sağlayıcılardan birinde bulunduğunda sistem, Ayrıntılarda uygulamanızın derin bağlantısını paylaşın diğer sağlayıcıların uygulamalarına giden bağlantılarla birlikte içeriği görüntüleyin. Bu konu Ayrıntılar ekranındaki uygulamanızın derin bağlantısı bölümüne gidin.
Uygulamanızın veritabanı sınıfı, sütunları şu şekilde tanımlayabilir:
Kotlin
class VideoDatabase { companion object { // The columns we'll include in the video database table val KEY_NAME = SearchManager.SUGGEST_COLUMN_TEXT_1 val KEY_DESCRIPTION = SearchManager.SUGGEST_COLUMN_TEXT_2 val KEY_ICON = SearchManager.SUGGEST_COLUMN_RESULT_CARD_IMAGE val KEY_DATA_TYPE = SearchManager.SUGGEST_COLUMN_CONTENT_TYPE val KEY_IS_LIVE = SearchManager.SUGGEST_COLUMN_IS_LIVE val KEY_VIDEO_WIDTH = SearchManager.SUGGEST_COLUMN_VIDEO_WIDTH val KEY_VIDEO_HEIGHT = SearchManager.SUGGEST_COLUMN_VIDEO_HEIGHT val KEY_AUDIO_CHANNEL_CONFIG = SearchManager.SUGGEST_COLUMN_AUDIO_CHANNEL_CONFIG val KEY_PURCHASE_PRICE = SearchManager.SUGGEST_COLUMN_PURCHASE_PRICE val KEY_RENTAL_PRICE = SearchManager.SUGGEST_COLUMN_RENTAL_PRICE val KEY_RATING_STYLE = SearchManager.SUGGEST_COLUMN_RATING_STYLE val KEY_RATING_SCORE = SearchManager.SUGGEST_COLUMN_RATING_SCORE val KEY_PRODUCTION_YEAR = SearchManager.SUGGEST_COLUMN_PRODUCTION_YEAR val KEY_COLUMN_DURATION = SearchManager.SUGGEST_COLUMN_DURATION val KEY_ACTION = SearchManager.SUGGEST_COLUMN_INTENT_ACTION ... } ... }
Java
public class VideoDatabase { // The columns we'll include in the video database table public static final String KEY_NAME = SearchManager.SUGGEST_COLUMN_TEXT_1; public static final String KEY_DESCRIPTION = SearchManager.SUGGEST_COLUMN_TEXT_2; public static final String KEY_ICON = SearchManager.SUGGEST_COLUMN_RESULT_CARD_IMAGE; public static final String KEY_DATA_TYPE = SearchManager.SUGGEST_COLUMN_CONTENT_TYPE; public static final String KEY_IS_LIVE = SearchManager.SUGGEST_COLUMN_IS_LIVE; public static final String KEY_VIDEO_WIDTH = SearchManager.SUGGEST_COLUMN_VIDEO_WIDTH; public static final String KEY_VIDEO_HEIGHT = SearchManager.SUGGEST_COLUMN_VIDEO_HEIGHT; public static final String KEY_AUDIO_CHANNEL_CONFIG = SearchManager.SUGGEST_COLUMN_AUDIO_CHANNEL_CONFIG; public static final String KEY_PURCHASE_PRICE = SearchManager.SUGGEST_COLUMN_PURCHASE_PRICE; public static final String KEY_RENTAL_PRICE = SearchManager.SUGGEST_COLUMN_RENTAL_PRICE; public static final String KEY_RATING_STYLE = SearchManager.SUGGEST_COLUMN_RATING_STYLE; public static final String KEY_RATING_SCORE = SearchManager.SUGGEST_COLUMN_RATING_SCORE; public static final String KEY_PRODUCTION_YEAR = SearchManager.SUGGEST_COLUMN_PRODUCTION_YEAR; public static final String KEY_COLUMN_DURATION = SearchManager.SUGGEST_COLUMN_DURATION; public static final String KEY_ACTION = SearchManager.SUGGEST_COLUMN_INTENT_ACTION; ...
SearchManager
sütunlarından veri alanlarınıza haritayı oluşturduğunuzda
her satıra benzersiz bir kimlik vermek için _ID
öğesi de belirtilmelidir.
Kotlin
companion object { .... private fun buildColumnMap(): MapS<tring, String> { return mapOf( KEY_NAME to KEY_NAME, KEY_DESCRIPTION to KEY_DESCRIPTION, KEY_ICON to KEY_ICON, KEY_DATA_TYPE to KEY_DATA_TYPE, KEY_IS_LIVE to KEY_IS_LIVE, KEY_VIDEO_WIDTH to KEY_VIDEO_WIDTH, KEY_VIDEO_HEIGHT to KEY_VIDEO_HEIGHT, KEY_AUDIO_CHANNEL_CONFIG to KEY_AUDIO_CHANNEL_CONFIG, KEY_PURCHASE_PRICE to KEY_PURCHASE_PRICE, KEY_RENTAL_PRICE to KEY_RENTAL_PRICE, KEY_RATING_STYLE to KEY_RATING_STYLE, KEY_RATING_SCORE to KEY_RATING_SCORE, KEY_PRODUCTION_YEAR to KEY_PRODUCTION_YEAR, KEY_COLUMN_DURATION to KEY_COLUMN_DURATION, KEY_ACTION to KEY_ACTION, BaseColumns._ID to ("rowid AS " + BaseColumns._ID), SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID to ("rowid AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID), SearchManager.SUGGEST_COLUMN_SHORTCUT_ID to ("rowid AS " + SearchManager.SUGGEST_COLUMN_SHORTCUT_ID) ) } }
Java
... private static HashMap<String, String> buildColumnMap() { HashMap<String, String> map = new HashMap<String, String>(); map.put(KEY_NAME, KEY_NAME); map.put(KEY_DESCRIPTION, KEY_DESCRIPTION); map.put(KEY_ICON, KEY_ICON); map.put(KEY_DATA_TYPE, KEY_DATA_TYPE); map.put(KEY_IS_LIVE, KEY_IS_LIVE); map.put(KEY_VIDEO_WIDTH, KEY_VIDEO_WIDTH); map.put(KEY_VIDEO_HEIGHT, KEY_VIDEO_HEIGHT); map.put(KEY_AUDIO_CHANNEL_CONFIG, KEY_AUDIO_CHANNEL_CONFIG); map.put(KEY_PURCHASE_PRICE, KEY_PURCHASE_PRICE); map.put(KEY_RENTAL_PRICE, KEY_RENTAL_PRICE); map.put(KEY_RATING_STYLE, KEY_RATING_STYLE); map.put(KEY_RATING_SCORE, KEY_RATING_SCORE); map.put(KEY_PRODUCTION_YEAR, KEY_PRODUCTION_YEAR); map.put(KEY_COLUMN_DURATION, KEY_COLUMN_DURATION); map.put(KEY_ACTION, KEY_ACTION); map.put(BaseColumns._ID, "rowid AS " + BaseColumns._ID); map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID); map.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, "rowid AS " + SearchManager.SUGGEST_COLUMN_SHORTCUT_ID); return map; } ...
Yukarıdaki örnekte, SUGGEST_COLUMN_INTENT_DATA_ID
girin. Bu, URI'nın bu verideki verilere özgü içeriğe işaret eden kısmıdır
satır: içeriğin nerede depolandığını açıklayan URI'nın son bölümü. URI'nın ilk kısmı,
tüm satırlar için ortak olduğunda,
searchable.xml
dosyasını
android:searchSuggestIntentData
özelliğini,
Arama önerilerini işleme bölümü.
URI'nın ilk bölümü,
bu değeri SUGGEST_COLUMN_INTENT_DATA
alanıyla eşleyin.
Kullanıcı bu içeriği seçtiğinde etkinleşen intent,
SUGGEST_COLUMN_INTENT_DATA_ID
kombinasyonu
ve android:searchSuggestIntentData
ya da
SUGGEST_COLUMN_INTENT_DATA
alan değeri.
Arama önerisi verileri sağlama
Bir İçerik Sağlayıcı'yı uygulama
tuşuna basarak Android TV arama iletişim kutusuna arama terimi önerileri alabilirsiniz. Sistem, içeriğinizi sorgular
her seferinde query()
yöntemini çağırarak öneriler için
harf yazılır. query()
uygulamanızda, içeriğiniz
sağlayıcı öneri verilerinizi arar veCursor
öneriler için belirlediğiniz satırlar.
Kotlin
fun query(uri: Uri, projection: Array<String>, selection: String, selectionArgs: Array<String>, sortOrder: String): Cursor { // Use the UriMatcher to see what kind of query we have and format the db query accordingly when (URI_MATCHER.match(uri)) { SEARCH_SUGGEST -> { Log.d(TAG, "search suggest: ${selectionArgs[0]} URI: $uri") if (selectionArgs == null) { throw IllegalArgumentException( "selectionArgs must be provided for the Uri: $uri") } return getSuggestions(selectionArgs[0]) } else -> throw IllegalArgumentException("Unknown Uri: $uri") } } private fun getSuggestions(query: String): Cursor { val columns = arrayOf<String>( BaseColumns._ID, VideoDatabase.KEY_NAME, VideoDatabase.KEY_DESCRIPTION, VideoDatabase.KEY_ICON, VideoDatabase.KEY_DATA_TYPE, VideoDatabase.KEY_IS_LIVE, VideoDatabase.KEY_VIDEO_WIDTH, VideoDatabase.KEY_VIDEO_HEIGHT, VideoDatabase.KEY_AUDIO_CHANNEL_CONFIG, VideoDatabase.KEY_PURCHASE_PRICE, VideoDatabase.KEY_RENTAL_PRICE, VideoDatabase.KEY_RATING_STYLE, VideoDatabase.KEY_RATING_SCORE, VideoDatabase.KEY_PRODUCTION_YEAR, VideoDatabase.KEY_COLUMN_DURATION, VideoDatabase.KEY_ACTION, SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID ) return videoDatabase.getWordMatch(query.toLowerCase(), columns) }
Java
@Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // Use the UriMatcher to see what kind of query we have and format the db query accordingly switch (URI_MATCHER.match(uri)) { case SEARCH_SUGGEST: Log.d(TAG, "search suggest: " + selectionArgs[0] + " URI: " + uri); if (selectionArgs == null) { throw new IllegalArgumentException( "selectionArgs must be provided for the Uri: " + uri); } return getSuggestions(selectionArgs[0]); default: throw new IllegalArgumentException("Unknown Uri: " + uri); } } private Cursor getSuggestions(String query) { query = query.toLowerCase(); String[] columns = new String[]{ BaseColumns._ID, VideoDatabase.KEY_NAME, VideoDatabase.KEY_DESCRIPTION, VideoDatabase.KEY_ICON, VideoDatabase.KEY_DATA_TYPE, VideoDatabase.KEY_IS_LIVE, VideoDatabase.KEY_VIDEO_WIDTH, VideoDatabase.KEY_VIDEO_HEIGHT, VideoDatabase.KEY_AUDIO_CHANNEL_CONFIG, VideoDatabase.KEY_PURCHASE_PRICE, VideoDatabase.KEY_RENTAL_PRICE, VideoDatabase.KEY_RATING_STYLE, VideoDatabase.KEY_RATING_SCORE, VideoDatabase.KEY_PRODUCTION_YEAR, VideoDatabase.KEY_COLUMN_DURATION, VideoDatabase.KEY_ACTION, SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID }; return videoDatabase.getWordMatch(query, columns); } ...
Manifest dosyanızda, içerik sağlayıcıya özel muamelede bulunuluyor. Bir proje yöneticisi
etkinlik olarak etiketlenmişse
<provider>
. İlgili içeriği oluşturmak için kullanılan
sağlayıcı, sisteme bu durumu bildirmek için android:authorities
özelliğini ekler.
alan adı olacaktır. Ayrıca, android:exported
özelliğini
Android genel aramasının, kendisinden döndürülen sonuçları kullanabilmesi için "true"
.
<provider android:name="com.example.android.tvleanback.VideoContentProvider" android:authorities="com.example.android.tvleanback" android:exported="true" />
Arama önerilerini işleme
Uygulamanız bir içermelidir
res/xml/searchable.xml
dosyasını kullanın.
res/xml/searchable.xml
dosyasına şunları ekleyin:
android:searchSuggestAuthority
özelliğini kullanabilirsiniz.
içerik sağlayıcı. Bu,
android:authorities
<provider>
özelliğinin özelliği
AndroidManifest.xml
dosyanızda öğesi.
Ayrıca bir etiket ekleyin, Bu, uygulamanın adıdır. Sistem arama ayarları numaralandırma sırasında bu etiketi kullanır arama yapabilirsiniz.
searchable.xml
dosyası
şunları da içermelidir:
"android.intent.action.VIEW"
değerine sahip android:searchSuggestIntentAction
amacına bağlı olarak kullanabilirsiniz. Bu, amaçtan farklıdır
arama terimi sağlamayla ilgili işlemler şunlardır:
Önerilerde intent işlemini bildirmenin diğer yolları için
bkz.
intent işlemidir.
Uygulamanız, intent işlemiyle birlikte
android:searchSuggestIntentData
özelliğini gönderin. Bu, URI'nın bunu gösteren ilk kısmıdır
söz konusu öğe için eşleme tablosundaki tüm satırlarda URI'nın ortak bölümünü açıklayan içeriğe
içerik. URI'nın her satır için benzersiz olan kısmı SUGGEST_COLUMN_INTENT_DATA_ID
alanıyla belirlenir.
Sütunları belirleme bölümünde açıklandığı gibi.
Öneriler için amaç verilerini beyan etmenin diğer yolları için bkz.
Beyan
amaç verileri.
android:searchSuggestSelection=" ?"
özelliği, iletilen değeri belirtir.
query()
öğesinin selection
parametresi olarak
yöntemidir. Soru işareti (?
) değeri sorgu metniyle değiştirilir.
Son olarak,
android:includeInGlobalSearch
özelliği "true"
değerine sahiptir. Bir örnekle açıklayalım
searchable.xml
dosyası:
<searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/search_label" android:hint="@string/search_hint" android:searchSettingsDescription="@string/settings_description" android:searchSuggestAuthority="com.example.android.tvleanback" android:searchSuggestIntentAction="android.intent.action.VIEW" android:searchSuggestIntentData="content://com.example.android.tvleanback/video_database_leanback" android:searchSuggestSelection=" ?" android:searchSuggestThreshold="1" android:includeInGlobalSearch="true"> </searchable>
Arama terimlerini işleme
Arama iletişim kutusunda, uygulamanızın sütunlarından birindeki değerle eşleşen bir kelime olduğunda
Sütunları belirleme bölümünde açıklandığından, sistem
Amaç ACTION_SEARCH
.
Uygulamanızda bunu işleyen etkinlik
intent, değerlerinde belirtilen kelimenin bulunduğu sütunlar için depoyu arar ve bir liste döndürür.
içerik öğelerini görebilirsiniz. AndroidManifest.xml
dosyanızda,
ACTION_SEARCH
için nasıl bir etkinlik
intent'i seçmeniz gerekir:
... <activity android:name="com.example.android.tvleanback.DetailsActivity" android:exported="true"> <!-- Receives the search request. --> <intent-filter> <action android:name="android.intent.action.SEARCH" /> <!-- No category needed, because the Intent will specify this class component --> </intent-filter> <!-- Points to searchable meta data. --> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity> ... <!-- Provides search suggestions for keywords against video meta data. --> <provider android:name="com.example.android.tvleanback.VideoContentProvider" android:authorities="com.example.android.tvleanback" android:exported="true" /> ...
Etkinlik, aynı zamanda
searchable.xml
dosyası olarak kaydedin.
Genel arama iletişim kutusunu kullanmak için
manifesto, hangi etkinliğin arama sorgularını alması gerektiğini açıklamalıdır. Manifest dosyası ayrıca
<provider>
öğesi, tam olarak searchable.xml
dosyasında açıklandığı gibi olmalıdır.
Ayrıntılar ekranında uygulamanıza derin bağlantı oluşturun
Arama yapılandırmasını Herkese açık kullanıcı adı arama
önerileri bölümünü inceledik ve SUGGEST_COLUMN_TEXT_1
öğesini eşledik.
SUGGEST_COLUMN_PRODUCTION_YEAR
ve
Şu şekilde açıklandığı gibi SUGGEST_COLUMN_DURATION
alan:
Sütunları belirleme bölümü,
içeriğinizle ilişkili bir izleme işleminin derin bağlantısı, aşağıdaki işlemler gerçekleştirildiğinde açılan ayrıntılar ekranında görünür.
kullanıcı bir arama sonucu seçer:
Kullanıcı uygulamanızın bağlantısını seçtiğinde,
ayrıntılar ekranında, sistem, ACTION_VIEW
işleyen etkinliği başlatır
olarak ayarla
Şu aralıkta "android.intent.action.VIEW"
değerine sahip android:searchSuggestIntentAction
:
searchable.xml
dosyası.
Etkinliğinizi başlatmak için özel amaç da oluşturabilirsiniz. Bu,
Leanback örnek uygulaması
, Örnek uygulamanın aşağıdaki işlemler için kendi LeanbackDetailsFragment
uygulamasını başlattığını unutmayın:
Seçilen medyanın ayrıntılarını gösterir; medya içeriklerini oynatan etkinliği başlatın,
kullanıcının bir veya iki tıklama daha kaydetmesi için hemen harekete geçin.
Arama davranışı
Arama, Android TV'de ana ekrandan ve uygulamanızın içinden kullanılabilir. Arama sonuçları birbirinden farklıdır.
Ana ekrandan arama yapın
Kullanıcı ana ekrandan arama yaptığında varlık kartında ilk sonuç görünür. Varsa içeriği oynatabilen uygulamaların bağlantısı kartın altında her birinin bağlantısı görünür:
Varlık kartına programlı bir şekilde uygulama yerleştiremezsiniz. Bir seçeneğini kullanmak isterseniz, uygulamanın arama sonuçları uygulamanın başlığı, yılı yardımcı olur.
Kartın altında daha fazla arama sonucu bulabilirsiniz. Bunları görmek için kullanıcı ekranın uzaktan kumanda edin ve aşağı kaydırın. Her uygulamaya ait sonuçlar ayrı bir satırda gösterilir. Bu seçeneği, satır sıralaması. Şu uygulamayı destekleyen uygulamalar: izleme işlemleri ilk sırada listelenir.
Uygulamanızdan arama
Kullanıcı uzaktan kumandadan mikrofonu başlatarak veya uygulamanın içinden de arama başlatabilir. oyun kumandası. Arama sonuçları, uygulama içeriğinin üzerinde tek bir satırda görüntülenir. Uygulamanız, arama sonuçlarını kendi genel arama sağlayıcısını kullanarak oluşturur.
Daha fazla bilgi
TV uygulamasında arama yapma hakkında daha fazla bilgi edinmek için şu makaleyi okuyun: Android arama özelliklerini uygulamanıza entegre edin ve Arama işlevi ekleyin.
SearchFragment
ile uygulama içi arama deneyimini özelleştirme hakkında daha fazla bilgi için şu makaleyi okuyun:
TV uygulamalarında arama yapma.