جعل تطبيقات التلفزيون قابلة للبحث

يستخدم Android TV واجهة البحث على Android. لاسترداد بيانات المحتوى من التطبيقات المثبّتة وعرض نتائج البحث للمستخدم. المعلومات عن تطبيقك يمكن تضمين بيانات المحتوى مع هذه النتائج لمنح المستخدم حق الوصول الفوري إلى المحتوى الموجود في تطبيقك.

يجب أن يوفِّر تطبيقك حقول البيانات التي يمكن لتطبيق Android TV من خلالها إنشاء بحث مقترَح. النتائج عندما يُدخل المستخدم أحرفًا في مربّع حوار البحث. لإجراء ذلك، يجب أن يستخدم تطبيقك موفّر المحتوى الذي يقدّم الخدمات الاقتراحات مع ملف إعداد searchable.xml يصف المحتوى المستخدم ومعلومات مهمة أخرى خاصة بـ Android TV. تحتاج أيضًا إلى نشاط يعالج يتم تنشيطها عندما يختار المستخدم نتيجة بحث مقترَحة. بالنسبة بمزيد من التفاصيل، راجع إضافة اقتراحات البحث المخصّصة. يتناول هذا الدليل النقاط الرئيسية المتعلّقة بتطبيقات Android TV.

قبل قراءة هذا الدليل، تأكد من أنك على دراية بالمفاهيم التي يتم شرحها في دليل واجهة برمجة تطبيقات البحث راجِع أيضًا المقالة إضافة وظيفة بحث.

يأتي الرمز النموذجي في هذا الدليل من نموذج تطبيق Leanback .

تحديد الأعمدة

تصف SearchManager حقول البيانات المتوقّعة من خلال تمثيلها على أنّها والأعمدة في قاعدة بيانات محلية. بغض النظر عن تنسيق بياناتك، يجب ربط حقول البيانات بها. هذه الأعمدة، وعادةً ما تكون في الفئة التي يمكنها الوصول إلى بيانات المحتوى لديك. للحصول على معلومات حول إنشاء فئة تربط بياناتك الحالية بالحقول المطلوبة، ويمكنك مراجعة إنشاء جدول اقتراحات

تتضمّن الفئة SearchManager عدة أعمدة لـ Android TV. يمكن استخدام الأعمدة الأكثر أهمية في الجدول التالي.

القيمة الوصف
SUGGEST_COLUMN_TEXT_1 اسم المحتوى (مطلوب)
SUGGEST_COLUMN_TEXT_2 وصف نصي للمحتوى الخاص بك
SUGGEST_COLUMN_RESULT_CARD_IMAGE صورة أو ملصق أو غلاف للمحتوى الخاص بك
SUGGEST_COLUMN_CONTENT_TYPE نوع MIME للوسائط
SUGGEST_COLUMN_VIDEO_WIDTH عرض درجة دقة الوسائط
SUGGEST_COLUMN_VIDEO_HEIGHT ارتفاع درجة دقة الوسائط
SUGGEST_COLUMN_PRODUCTION_YEAR سنة إنتاج المحتوى (مطلوب)
SUGGEST_COLUMN_DURATION المدة بالمللي ثانية للوسائط (مطلوبة)

يتطلب إطار عمل البحث الأعمدة التالية:

عندما تتطابق قيم هذه الأعمدة للمحتوى الخاص بك مع قيم المحتوى نفسه من المقدمة من خوادم Google، فإن النظام يوفر رابط لصفحة في التطبيق إلى تطبيقك بالتفصيل والاطّلاع على المحتوى، بالإضافة إلى روابط إلى تطبيقات مقدّمي الخدمة الآخرين. تمت مناقشة هذا أكثر في قسم رابط لموضع معيّن في تطبيقك في شاشة التفاصيل.

قد تحدد فئة قاعدة البيانات في تطبيقك الأعمدة على النحو التالي:

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 إلى حقول البيانات، يمكنك تنفيذ ما يلي: يجب أيضًا تحديد _ID لمنح كل صف معرّفًا فريدًا.

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;
  }
...

في المثال السابق، لاحِظ عملية الربط بالسمة SUGGEST_COLUMN_INTENT_DATA_ID. . هذا هو الجزء من عنوان URI الذي يشير إلى المحتوى الفريد للبيانات في الصف - الجزء الأخير من عنوان URI، الذي يصف مكان تخزين المحتوى. الجزء الأول من عنوان URI، عندما يكون من الشائع لجميع الصفوف في الجدول، يتم تعيينها في searchable.xml باعتباره ملف android:searchSuggestIntentData كما هو موضَّح في قسم التعامل مع اقتراحات البحث:

إذا كان الجزء الأول من عنوان URI مختلفًا لكل صف في ، فيجب ربط هذه القيمة بالحقل SUGGEST_COLUMN_INTENT_DATA. عندما يختار المستخدم هذا المحتوى، يوفّر الغرض الذي يتم تنشيطه بيانات النية من تركيبة من SUGGEST_COLUMN_INTENT_DATA_ID بالإضافة إلى السمة android:searchSuggestIntentData أو قيمة الحقل SUGGEST_COLUMN_INTENT_DATA.

تقديم بيانات اقتراحات البحث

استخدام موفّر محتوى لإعادة اقتراحات عبارات البحث إلى مربّع حوار البحث في Android TV. يرسل النظام طلبات بحث إلى المحتوى الخاص بك للحصول على اقتراحات من خلال استدعاء طريقة query() في كل مرة تتم كتابة حرف. أثناء تنفيذ query()، سيتضمن المحتوى الخاص بك البحث في بيانات الاقتراح وعرض رمز الاستجابة Cursor الذي يشير إلى الصفوف التي قمت بتعيينها للاقتراحات.

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);
}
...

في ملف البيان، يتلقّى موفّر المحتوى معاملة خاصة. بدلاً من أن تكون موضوع علامة عليه باعتباره نشاطًا، في يتم وصفه بأنه <provider> تشير رسالة الأشكال البيانية يتضمّن موفِّر خدمة السمة android:authorities لإبلاغ النظام مساحة الاسم لموفّر المحتوى يجب أيضًا ضبط سمة android:exported على "true" حتى يتمكّن البحث العام على Android من استخدام النتائج المعروضة منه.

<provider android:name="com.example.android.tvleanback.VideoContentProvider"
    android:authorities="com.example.android.tvleanback"
    android:exported="true" />

التعامل مع اقتراحات البحث

يجب أن يتضمن تطبيقك res/xml/searchable.xml لضبط إعدادات اقتراحات البحث.

في ملف res/xml/searchable.xml، قم بتضمين android:searchSuggestAuthority لإعلام النظام بمساحة الاسم في المحتوى. ويجب أن يُطابق هذا قيمة السلسلة التي تحددها في android:authorities سمة <provider> في ملف AndroidManifest.xml.

عليك أيضًا تضمين تصنيف، وهو اسم التطبيق. تستخدم إعدادات بحث النظام هذا التصنيف عند التعداد. وتطبيقات قابلة للبحث.

الملف searchable.xml على android:searchSuggestIntentAction بالقيمة "android.intent.action.VIEW" لتحديد الإجراء المقصود لتقديم اقتراح مخصّص ويختلف هذا عن المقصد لتقديم عبارة بحث، كما هو موضّح في القسم التالي. بالنسبة إلى الطرق الأخرى للإعلان عن الإجراء المقصود للاقتراحات، راجع إعلان إجراء intent.

إلى جانب إجراء الهدف، يجب أن يقدِّم تطبيقك بيانات intent التي تحدِّدها باستخدام android:searchSuggestIntentData. هذا هو الجزء الأول من عنوان URI الذي يشير إلى إلى المحتوى، والذي يصف جزء عنوان URI المشترك بين جميع الصفوف في جدول التعيين لذلك المحتوى. يتم إنشاء الجزء الفريد لكل صف من معرف الموارد المنتظم (URI) باستخدام الحقل SUGGEST_COLUMN_INTENT_DATA_ID، كما هو موضح في قسم تحديد الأعمدة. للتعرّف على الطرق الأخرى للإعلان عن بيانات الغرض من الاقتراحات، يُرجى الاطّلاع على الإقرار بيانات النية بالشراء.

تحدّد السمة android:searchSuggestSelection=" ?" القيمة التي تم ضبطها. باعتبارها المعلمة selection للدالة query() . يتم استبدال قيمة علامة الاستفهام (?) بنص طلب البحث.

أخيرًا، يجب أيضًا تضمين android:includeInGlobalSearch بالقيمة "true". إليك مثالاً ملف searchable.xml:

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

التعامل مع عبارات البحث

وبمجرد أن يحتوي مربع حوار البحث على كلمة تُطابق القيمة الموجودة في أحد أعمدة التطبيق، مثل كما هو موضح في قسم تحديد الأعمدة، سيعمل النظام على تنشيط هدف واحد (ACTION_SEARCH) يشير هذا المصطلح إلى النشاط في تطبيقك الذي يعالج ذلك. يبحث الغرض في المستودع عن الأعمدة التي تحتوي على الكلمة المحددة في قيمها ويعرض قائمة عناصر المحتوى باستخدام هذه الأعمدة. في ملف AndroidManifest.xml، يمكنك تحديد النشاط الذي يعالج ACTION_SEARCH الغرض كما هو موضح في المثال التالي:

...
  <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" />
...

يجب أن يصف النشاط أيضًا التهيئة القابلة للبحث مع إشارة إلى searchable.xml. لاستخدام مربع حوار البحث العام، يجب أن يصف البيان النشاط الذي يجب أن يتلقى طلبات البحث. يجب أن يتضمن البيان أيضًا وصف <provider> ، تمامًا كما هو موضَّح في ملف searchable.xml.

رابط لموضع معيّن في تطبيقك في شاشة التفاصيل

في حال ضبط إعدادات البحث كما هو موضَّح في قسم الاسم المعرِّف الاقتراحات وربطت SUGGEST_COLUMN_TEXT_1، SUGGEST_COLUMN_PRODUCTION_YEAR، حقلان (SUGGEST_COLUMN_DURATION) كما هو موضّح في قسم تحديد الأعمدة، قسم رابط لصفحة في التطبيق يؤدي إلى إجراء مشاهدة للمحتوى الخاص بك يظهر في شاشة التفاصيل التي يتم تشغيلها عند اختيار المستخدم لنتيجة بحث:

رابط لموضع معيّن في شاشة التفاصيل

عندما ينقر المستخدم على رابط تطبيقك، المحدّد من خلال الزر **متاح على** في شاشة التفاصيل، سيطلق النظام النشاط الذي يعالج ACTION_VIEW تعيين كـ android:searchSuggestIntentAction بالقيمة "android.intent.action.VIEW" في ملف searchable.xml.

يمكنك أيضًا إعداد نيّة شراء مخصّصة لإطلاق نشاطك. يتجلى ذلك في نموذج تطبيق Leanback . تجدر الإشارة إلى أنّ نموذج التطبيق يشغِّل LeanbackDetailsFragment من أجل إظهار تفاصيل الوسائط المحددة في تطبيقاتك، ابدأ تشغيل النشاط الذي يشغّل الوسائط على الفور لتوفير نقرة أخرى أو اثنتين على المستخدم.

سلوك البحث

تتوفّر ميزة البحث في Android TV من الشاشة الرئيسية ومن داخل تطبيقك. نتائج البحث تختلفان في هاتين الحالتين.

البحث من الشاشة الرئيسية

عندما يبحث المستخدم من الشاشة الرئيسية، تظهر النتيجة الأولى في بطاقة الكيان. إذا كانت هناك تطبيقات يمكنها تشغيل المحتوى، سيظهر رابط لكل تطبيق في أسفل البطاقة:

تشغيل نتيجة البحث عن التلفزيون

لا يمكنك وضع تطبيق آليًا في بطاقة الكيان. لكي يتم إدراجك كـ لتشغيل المحتوى، فيجب أن تتطابق نتائج بحث التطبيق مع العنوان والسنة والمدة في المحتوى.

قد يظهر المزيد من نتائج البحث أسفل البطاقة. لمشاهدتها، يجب أن يضغط المستخدم لأسفل على عن بُعد والانتقال لأسفل. تظهر نتائج كل تطبيق في صف منفصل. لا يمكنك التحكم في ترتيب الصفوف. التطبيقات المتوافقة إجراءات المشاهدة مُدرجة أولاً.

نتائج البحث عن البرامج التلفزيونية

البحث من تطبيقك

يمكن للمستخدم أيضًا بدء عملية بحث من داخل التطبيق من خلال تشغيل الميكروفون من جهاز التحكّم عن بُعد أو ذراع التحكّم في لوحة الألعاب يتم عرض نتائج البحث في صف واحد أعلى محتوى التطبيق. يُنشئ تطبيقك نتائج بحث باستخدام مزوّد خدمة البحث العالمي الخاص به.

نتائج البحث داخل التطبيقات التلفزيونية

مزيد من المعلومات

لمعرفة المزيد من المعلومات حول البحث عن تطبيق تلفزيون، يمكنك قراءة دمج ميزات البحث على Android في تطبيقك إضافة وظيفة بحث:

لمزيد من المعلومات حول طريقة تخصيص تجربة البحث داخل التطبيق باستخدام SearchFragment، يُرجى الاطّلاع على البحث داخل تطبيقات التلفزيون