إضافة اقتراحات بحث مخصّص

تجربة طريقة "الكتابة"
‫Jetpack Compose هي مجموعة أدوات واجهة المستخدم التي يُنصح باستخدامها على Android. تعرَّف على كيفية إضافة وظيفة البحث في "إنشاء".

عند استخدام مربّع حوار البحث أو أداة البحث على Android، يمكنك تقديم اقتراحات بحث مخصّصة يتم إنشاؤها من البيانات في تطبيقك. على سبيل المثال، إذا كان تطبيقك عبارة عن قاموس، يمكنك اقتراح كلمات من القاموس تتطابق مع النص الذي تم إدخاله في حقل البحث قبل أن ينتهي المستخدم من إدخال طلبه. هذه الاقتراحات مفيدة لأنّها يمكن أن تتوقّع بشكل فعّال ما يريده المستخدم وتوفّر له إمكانية الوصول إليه على الفور. تعرض "الشكل 1" مثالاً على مربّع حوار بحث يتضمّن اقتراحات مخصّصة.

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

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

الأساسيات

الشكل 1. لقطة شاشة لمربّع حوار بحث يتضمّن اقتراحات بحث مخصّصة

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

لتقديم اقتراحات مخصّصة، اتّبِع الخطوات التالية:

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

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

عندما يرصد النظام أنّ نشاطك قابل للبحث ويقدّم اقتراحات بحث، يتم اتّباع الإجراء التالي عندما يُدخل المستخدم طلب بحث:

  1. يأخذ النظام نص عبارة البحث، أي كل ما تم إدخاله حتى الآن، وينفّذ طلب بحث إلى مقدّم المحتوى الذي يدير اقتراحاتك.
  2. يعرض مقدّم المحتوى Cursor يشير إلى جميع الاقتراحات ذات الصلة بنص طلب البحث.
  3. يعرض النظام قائمة بالاقتراحات المقدَّمة من Cursor.

بعد عرض الاقتراحات المخصّصة، قد يحدث ما يلي:

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

تعديل الإعداد القابل للبحث

لإتاحة الاقتراحات المخصّصة، أضِف السمة android:searchSuggestAuthority إلى العنصر <searchable> في ملف الإعداد القابل للبحث، كما هو موضّح في المثال التالي:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_label"
    android:hint="@string/search_hint"
    android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider">
</searchable>

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

إنشاء أداة توفير المحتوى

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

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

تتوفّر تفاصيل حول إنشاء مقدّم محتوى للاقتراحات المخصّصة في القسمَين التاليَين:

التعامل مع طلب البحث الخاص بالاقتراحات
كيفية إرسال النظام طلبات إلى مقدّم المحتوى وكيفية التعامل معها
إنشاء جدول اقتراحات
كيفية تحديد الأعمدة التي يتوقّع النظام أن يتم عرضها Cursor مع كل طلب بحث

التعامل مع طلب البحث الخاص بالاقتراح

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

في ما يلي ملخّص للمعلمات التي يمرّرها النظام إلى طريقة query()، مع إدراجها بالترتيب:

  1. uri

    يجب أن يكون المحتوى دائمًا Uri، ويكون التنسيق على النحو التالي:

    content://your.authority/optional.suggest.path/SUGGEST_URI_PATH_QUERY
    

    السلوك التلقائي هو أن يمرّر النظام معرّف الموارد المنتظم هذا ويضيف إليه نص طلب البحث:

    content://your.authority/optional.suggest.path/SUGGEST_URI_PATH_QUERY/puppies
    

    يتم ترميز نص طلب البحث في النهاية باستخدام قواعد ترميز URI، لذا قد تحتاج إلى فك ترميزه قبل إجراء عملية بحث.

    لا يتم تضمين الجزء optional.suggest.path إلا في معرّف الموارد المنتظم (URI) إذا ضبطت مسارًا كهذا في ملف الإعداد القابل للبحث باستخدام السمة android:searchSuggestPath. ولا يكون ذلك ضروريًا إلا إذا كنت تستخدم موفّر المحتوى نفسه لأنشطة متعدّدة قابلة للبحث. في هذه الحالة، يجب إزالة الغموض عن مصدر طلب البحث الخاص بالاقتراح.

  2. projection
    لا يتضمّن قيمة دائمًا.
  3. selection
    القيمة المقدَّمة في السمة android:searchSuggestSelection ضمن ملف الإعداد القابل للبحث، أو القيمة null إذا لم تحدّد السمة android:searchSuggestSelection. يتناول القسم التالي هذا الموضوع بالتفصيل.
  4. selectionArgs
    يحتوي على طلب البحث كالعنصر الأول والوحيد في المصفوفة إذا حدّدت السمة android:searchSuggestSelection في إعدادات البحث. إذا لم يتم تعريف android:searchSuggestSelection، ستكون قيمة هذه المَعلمة فارغة. يتناول القسم التالي هذا الموضوع بالتفصيل.
  5. sortOrder
    لا يتضمّن قيمة دائمًا.

يمكن أن يرسل إليك النظام نص طلب البحث بطريقتَين. الطريقة التلقائية هي تضمين نص طلب البحث كآخر مسار لعنوان URI الخاص بالمحتوى الذي تم تمريره في المَعلمة uri. ومع ذلك، إذا أدرجت قيمة اختيار في السمة android:searchSuggestSelection ضمن إعدادات البحث، سيتم تمرير نص طلب البحث كعنصر أول في مصفوفة السلسلة selectionArgs. سيتم توضيح هذين الخيارين في ما يلي.

الحصول على طلب البحث في عنوان URI

يتمّ إلحاق طلب البحث تلقائيًا كآخر جزء من المَعلمة uri، أي كائن Uri. لاسترداد نص طلب البحث في هذه الحالة، استخدِم getLastPathSegment()، كما هو موضّح في المثال التالي:

Kotlin

val query: String = uri.lastPathSegment.toLowerCase()

Java

String query = uri.getLastPathSegment().toLowerCase();

تعرض هذه السمة آخر جزء من Uri، وهو نص طلب البحث الذي يدخله المستخدم.

الحصول على طلب البحث في وسيطات التحديد

بدلاً من استخدام معرّف الموارد المنتظم (URI)، قد يكون من الأنسب أن تتلقّى الطريقة query() كل ما تحتاج إليه لتنفيذ عملية البحث، وقد تحتاج إلى أن تحمل المَعلمتَين selection وselectionArgs القيم المناسبة. في هذه الحالة، أضِف السمة android:searchSuggestSelection إلى إعدادات البحث مع سلسلة اختيار SQLite. في سلسلة الاختيار، أدرِج علامة استفهام (؟) كعنصر نائب لطلب البحث الفعلي. يستدعي النظام query() مع سلسلة التحديد كالمَعلمة selection وطلب البحث كالعنصر الأول في مصفوفة selectionArgs.

على سبيل المثال، إليك كيفية إنشاء السمة android:searchSuggestSelection لإنشاء عبارة بحث بنص كامل:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_label"
    android:hint="@string/search_hint"
    android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"
    android:searchSuggestIntentAction="android.intent.action.VIEW"
    android:searchSuggestSelection="word MATCH ?">
</searchable>

باستخدام هذا الإعداد، تعرض طريقتك query() المَعلمة selection كـ "word MATCH ?" والمَعلمة selectionArgs كطلب البحث. عند تمرير هذه القيم إلى إحدى طرق query() SQLite ، يتم دمجها معًا كمعلمات خاصة بها، أي يتم استبدال علامة الاستفهام بنص الاستعلام. إذا تلقّيت طلبات بحث تتضمّن اقتراحات بهذه الطريقة وكنت بحاجة إلى إضافة أحرف بدل إلى نص طلب البحث، ألحِقها أو أضِفها كبادئة إلى المَعلمة selectionArgs، لأنّ هذه القيمة تكون مضمّنة بين علامتَي اقتباس ويتم إدراجها بدلاً من علامة الاستفهام.

سمة أخرى في المثال السابق هي android:searchSuggestIntentAction، والتي تحدّد إجراء النية المرسَل مع كل نية عندما يختار المستخدم اقتراحًا. ويتم تناول هذا الموضوع بمزيد من التفصيل في قسم تحديد الغرض من الاقتراحات.

إنشاء جدول اقتراحات

عند إعادة الاقتراحات إلى النظام باستخدام Cursor، يتوقّع النظام أعمدة معيّنة في كل صف. بغض النظر عمّا إذا كنت تخزّن بيانات الاقتراحات في قاعدة بيانات SQLite على الجهاز أو في قاعدة بيانات على خادم ويب أو بتنسيق آخر على الجهاز أو الويب، يجب تنسيق الاقتراحات كصفوف في جدول وعرضها باستخدام Cursor.

يفهم النظام عدة أعمدة، ولكن هناك عمودان فقط مطلوبان:

_ID
معرّف صف فريد لكل اقتراح. ويطلب النظام ذلك لعرض الاقتراحات في ListView.
SUGGEST_COLUMN_TEXT_1
السلسلة التي يتم عرضها كاقتراح.

جميع الأعمدة التالية اختيارية. وسنتناول معظمها بالتفصيل في الأقسام التالية.

SUGGEST_COLUMN_TEXT_2
سلسلة إذا كان Cursor يتضمّن هذا العمود، سيتم تقديم جميع الاقتراحات بتنسيق من سطرَين. يتم عرض السلسلة في هذا العمود على شكل سطر ثانٍ أصغر من النص أسفل نص الاقتراح الأساسي. يمكن أن تكون القيمة فارغة أو صفرًا للإشارة إلى عدم توفّر نص ثانوي.
SUGGEST_COLUMN_ICON_1
سلسلة معرّف موارد منتظم (URI) لملف أو محتوى أو مورد قابل للرسم إذا كان Cursor يتضمّن هذا العمود، سيتم تقديم جميع الاقتراحات بتنسيق رمز بالإضافة إلى نص، مع وضع رمز العنصر القابل للرسم على الجانب الأيمن. يمكن أن تكون هذه القيمة فارغة أو صفرًا للإشارة إلى عدم توفّر رمز في هذا الصف.
SUGGEST_COLUMN_ICON_2
سلسلة معرّف موارد منتظم (URI) لملف أو محتوى أو مورد قابل للرسم إذا كان Cursor يتضمّن هذا العمود، سيتم تقديم كل الاقتراحات بتنسيق رمز بالإضافة إلى نص، مع ظهور الرمز على الجانب الأيسر. يمكن أن تكون القيمة فارغة أو صفرًا للإشارة إلى عدم توفّر رمز في هذا الصف.
SUGGEST_COLUMN_INTENT_ACTION
سلسلة إجراء الهدف في حال توفّر هذا العمود واحتوائه على قيمة في الصف المحدّد، يتم استخدام الإجراء المحدّد هنا عند إنشاء الغرض من الاقتراح. في حال عدم توفير العنصر، يتم اتّخاذ الإجراء من الحقل android:searchSuggestIntentAction في الإعدادات القابلة للبحث. إذا كان الإجراء هو نفسه لجميع الاقتراحات، سيكون من الأفضل تحديد الإجراء باستخدام android:searchSuggestIntentAction وحذف هذا العمود.
SUGGEST_COLUMN_INTENT_DATA
سلسلة معرّف موارد منتظم للبيانات إذا كان هذا العمود متوفّرًا ويتضمّن قيمة في الصف المحدّد، يتم استخدام هذه البيانات عند إنشاء هدف الاقتراح. في حال عدم توفير العنصر، يتم أخذ البيانات من الحقل android:searchSuggestIntentData في إعدادات البحث. إذا لم يتم توفير أي من المصدرين، سيكون حقل بيانات الغرض فارغًا. إذا كانت بياناتك هي نفسها بالنسبة إلى جميع الاقتراحات، أو إذا كان يمكن وصفها باستخدام جزء ثابت ومعرّف محدّد، سيكون من الأفضل تحديدها باستخدام android:searchSuggestIntentData وحذف هذا العمود.
SUGGEST_COLUMN_INTENT_DATA_ID
سلسلة مسار معرّف الموارد المنتظم (URI) إذا كان هذا العمود متوفّرًا ويتضمّن قيمة في الصف المحدّد، تتم إضافة "/" والقيمة إلى حقل البيانات في الغرض. لا تستخدِم هذه السمة إلا إذا كان حقل البيانات المحدّد بواسطة السمة android:searchSuggestIntentData في إعدادات البحث قابلاً للبحث قد تم ضبطه مسبقًا على سلسلة أساسية مناسبة.
SUGGEST_COLUMN_INTENT_EXTRA_DATA
بيانات عشوائية: إذا كان هذا العمود متوفّرًا ويتضمّن قيمة في صف معيّن، ستكون هذه البيانات هي البيانات الإضافية المستخدَمة عند إنشاء الغرض من الاقتراح. إذا لم يتم توفيرها، سيكون حقل البيانات الإضافية للغرض فارغًا. يتيح هذا العمود للاقتراحات توفير بيانات إضافية يتم تضمينها كبيانات إضافية في مفتاح EXTRA_DATA_KEY الغرض.
SUGGEST_COLUMN_QUERY
إذا كان هذا العمود وهذا العنصر متوفّرَين في الصف المحدّد، ستُستخدَم هذه البيانات عند إنشاء طلب البحث الخاص بالاقتراح، وسيتم تضمينها كعنصر إضافي في مفتاح QUERY intent. هذه السمة مطلوبة إذا كان الإجراء المقترَح هو ACTION_SEARCH، ولكنّها اختيارية في الحالات الأخرى.
SUGGEST_COLUMN_SHORTCUT_ID
تُستخدَم فقط عند تقديم اقتراحات لمربّع "البحث السريع". يشير هذا العمود إلى ما إذا كان يجب تخزين اقتراح البحث كاختصار وما إذا كان يجب التحقّق من صحته. يتم إنشاء الاختصارات عادةً عندما ينقر المستخدم على اقتراح من &quot;مربّع البحث السريع&quot;. في حال عدم توفّره، يتم تخزين النتيجة كاختصار ولا تتم إعادة تحميلها أبدًا. إذا تم ضبطها على SUGGEST_NEVER_MAKE_SHORTCUT، لن يتم تخزين النتيجة كاختصار. في الحالات الأخرى، يتم استخدام معرّف الاختصار للتحقّق من توفّر اقتراح حديث باستخدام SUGGEST_URI_PATH_SHORTCUT.
SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING
تُستخدَم فقط عند تقديم اقتراحات لمربّع "البحث السريع". يحدّد هذا العمود أنّه يجب عرض عجلة دوّارة بدلاً من رمز من SUGGEST_COLUMN_ICON_2 أثناء إعادة تحميل اختصار هذا الاقتراح في &quot;مربّع البحث السريع&quot;.

نتناول معظم هذه الأعمدة بالتفصيل في الأقسام التالية.

تعريف غرض الاقتراحات

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

تعريف إجراء Intent

إنّ إجراء النية الأكثر شيوعًا لاقتراح مخصّص هو ACTION_VIEW، وهو مناسب عندما تريد فتح شيء ما، مثل تعريف كلمة أو معلومات الاتصال بشخص أو صفحة ويب. ومع ذلك، يمكن أن يكون إجراء الهدف أي إجراء آخر ويمكن أن يختلف لكل اقتراح.

استنادًا إلى ما إذا كنت تريد أن تستخدم جميع الاقتراحات إجراء النية نفسه، يمكنك تحديد الإجراء بطريقتَين:

  • استخدِم السمة android:searchSuggestIntentAction في ملف الإعداد القابل للبحث لتحديد الإجراء لجميع الاقتراحات، كما هو موضّح في المثال التالي:
    <?xml version="1.0" encoding="utf-8"?>
    <searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/app_label"
        android:hint="@string/search_hint"
        android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"
        android:searchSuggestIntentAction="android.intent.action.VIEW" >
    </searchable>
  • استخدِم عمود SUGGEST_COLUMN_INTENT_ACTION لتحديد الإجراء الخاص بكل اقتراح. لإجراء ذلك، أضِف العمود SUGGEST_COLUMN_INTENT_ACTION إلى جدول الاقتراحات، ثم ضَع الإجراء المطلوب استخدامه لكل اقتراح، مثل "android.intent.action.VIEW".

يمكنك أيضًا الجمع بين هاتين الطريقتين. على سبيل المثال، يمكنك تضمين السمة android:searchSuggestIntentAction مع إجراء سيتم استخدامه مع جميع الاقتراحات تلقائيًا، ثم إلغاء هذا الإجراء لبعض الاقتراحات من خلال تحديد إجراء مختلف في العمود SUGGEST_COLUMN_INTENT_ACTION. إذا لم تدرِج قيمة في العمود SUGGEST_COLUMN_INTENT_ACTION، سيتم استخدام الغرض المقدَّم في السمة android:searchSuggestIntentAction.

إعلان بيانات النية

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

يمكنك تحديد البيانات المضمّنة في الغرض بطريقتين:

  • حدِّد البيانات لكل اقتراح داخل العمود SUGGEST_COLUMN_INTENT_DATA في جدول الاقتراحات.

    قدِّم جميع معلومات البيانات اللازمة لكل هدف في جدول الاقتراحات من خلال تضمين العمود SUGGEST_COLUMN_INTENT_DATA ثم ملء هذا العمود ببيانات فريدة لكل صف. يتم إرفاق البيانات من هذا العمود بالقصد تمامًا كما تحدّده في هذا العمود. يمكنك بعد ذلك استردادها باستخدام getData() أو getDataString().

  • قسِّم معرّف الموارد الموحّد للبيانات إلى جزأين: الجزء المشترك بين جميع الاقتراحات والجزء الفريد لكل اقتراح. ضَع هذه الأجزاء في السمة android:searchSuggestintentData الخاصة بإعدادات البحث وفي العمود SUGGEST_COLUMN_INTENT_DATA_ID الخاص بجدول الاقتراحات، على التوالي.

    يوضّح المثال التالي كيفية تعريف جزء معرّف الموارد المنتظم (URI) المشترك بين جميع الاقتراحات في السمة android:searchSuggestIntentData الخاصة بإعدادات البحث:

      <?xml version="1.0" encoding="utf-8"?>
      <searchable xmlns:android="http://schemas.android.com/apk/res/android"
          android:label="@string/app_label"
          android:hint="@string/search_hint"
          android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"
          android:searchSuggestIntentAction="android.intent.action.VIEW"
          android:searchSuggestIntentData="content://com.example/datatable" >
      </searchable>
      

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

إضافة المزيد من البيانات

إذا كنت بحاجة إلى التعبير عن المزيد من المعلومات باستخدام نيتك، يمكنك إضافة عمود جدول آخر، مثل SUGGEST_COLUMN_INTENT_EXTRA_DATA، والذي يمكنه تخزين معلومات إضافية حول الاقتراح. يتم وضع البيانات المحفوظة في هذا العمود في EXTRA_DATA_KEY لحزمة البيانات الإضافية الخاصة بالغرض.

التعامل مع النية

بعد تقديم اقتراحات بحث مخصّصة باستخدام أهداف مخصّصة، عليك أن تجعل نشاطك القابل للبحث يتعامل مع هذه الأهداف عندما يختار المستخدم اقتراحًا. يُضاف ذلك إلى معالجة ACTION_SEARCH intent، وهو ما يفعله نشاطك القابل للبحث حاليًا. في ما يلي مثال على كيفية التعامل مع الأهداف أثناء تنفيذ دالة onCreate() الرجوع الخاصة بنشاطك:

Kotlin

when(intent.action) {
    Intent.ACTION_SEARCH -> {
        // Handle the normal search query case.
        intent.getStringExtra(SearchManager.QUERY)?.also { query ->
            doSearch(query)
        }
    }
    Intent.ACTION_VIEW -> {
        // Handle a suggestions click, because the suggestions all use ACTION_VIEW.
        showResult(intent.data)
    }
}

Java

Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
    // Handle the normal search query case.
    String query = intent.getStringExtra(SearchManager.QUERY);
    doSearch(query);
} else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
    // Handle a suggestions click, because the suggestions all use ACTION_VIEW.
    Uri data = intent.getData();
    showResult(data);
}

في هذا المثال، يكون إجراء الغرض هو ACTION_VIEW وتحمل البيانات معرّف URI كاملاً يشير إلى العنصر المقترَح، كما تم إنشاؤه بواسطة السلسلة android:searchSuggestIntentData والعمود SUGGEST_COLUMN_INTENT_DATA_ID. ثم يتم تمرير معرّف الموارد المنتظم إلى طريقة showResult() المحلية التي تستعلم من موفّر المحتوى عن العنصر المحدّد بواسطة معرّف الموارد المنتظم.

إعادة كتابة نص طلب البحث

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

يمكنك إعادة كتابة نص طلب البحث بالطرق التالية:

  • أضِف السمة android:searchMode إلى إعداداتك القابلة للبحث مع القيمة "queryRewriteFromText". في هذه الحالة، يتم استخدام المحتوى من عمود SUGGEST_COLUMN_TEXT_1 في الاقتراح لإعادة كتابة نص طلب البحث.
  • أضِف السمة android:searchMode إلى إعداداتك القابلة للبحث مع القيمة "queryRewriteFromData". في هذه الحالة، يتم استخدام المحتوى من العمود SUGGEST_COLUMN_INTENT_DATA في الاقتراح لإعادة كتابة نص طلب البحث. لا تستخدِم هذه السمة إلا مع معرّفات الموارد المنتظمة (URI) أو تنسيقات البيانات الأخرى التي يُفترض أن تكون مرئية للمستخدم، مثل عناوين URL الخاصة ببروتوكول HTTP. ولا تستخدِم أنظمة معرّفات الموارد المنتظمة الداخلية لإعادة كتابة طلب البحث بهذه الطريقة.
  • قدِّم سلسلة نصية فريدة لطلب البحث في العمود SUGGEST_COLUMN_QUERY ضمن جدول الاقتراحات. إذا كان هذا العمود متوفّرًا ويتضمّن قيمة للاقتراح الحالي، يتم استخدامه لإعادة كتابة نص طلب البحث وتجاوز أي من عمليات التنفيذ السابقة.

عرض اقتراحات البحث في "مربّع البحث السريع"

بعد ضبط تطبيقك لتقديم اقتراحات بحث مخصّصة، يمكنك إتاحتها في &quot;مربّع البحث السريع&quot; المتاح للجميع بسهولة من خلال تعديل إعدادات البحث لتضمين android:includeInGlobalSearch بالقيمة "true".

الحالة الوحيدة التي يتطلّب فيها الأمر اتّخاذ إجراء إضافي هي عندما يطلب موفّر المحتوى إذنًا بالقراءة. في هذه الحالة، عليك إضافة عنصر <path-permission> إلى الموفّر لمنح ميزة &quot;شريط البحث السريع&quot; إذن الوصول للقراءة إلى موفّر المحتوى، كما هو موضّح في المثال التالي:

<provider android:name="MySuggestionProvider"
          android:authorities="com.example.MyCustomSuggestionProvider"
          android:readPermission="com.example.provider.READ_MY_DATA"
          android:writePermission="com.example.provider.WRITE_MY_DATA">
  <path-permission android:pathPrefix="/search_suggest_query"
                   android:readPermission="android.permission.GLOBAL_SEARCH" />
</provider>

في هذا المثال، يقيّد مقدّم الخدمة إذن القراءة والكتابة في ما يخص المحتوى. يعدّل العنصر <path-permission> القيود من خلال منح إذن القراءة للمحتوى داخل بادئة المسار "/search_suggest_query" عند توفّر الإذن "android.permission.GLOBAL_SEARCH". يمنح هذا الإذن إمكانية الوصول إلى &quot;مربّع البحث السريع&quot; كي يتمكّن من طلب اقتراحات من مقدّم المحتوى.

إذا كان مقدّم المحتوى لا يفرض أذونات القراءة، سيقرأ تطبيق &quot;شريط البحث السريع&quot; المحتوى تلقائيًا.

تفعيل الاقتراحات على جهاز

لا تكون التطبيقات مفعّلة بشكل تلقائي لتقديم اقتراحات في &quot;مربّع البحث السريع&quot;، حتى إذا تم ضبطها على ذلك. يختار المستخدم ما إذا كان سيتم تضمين اقتراحات من تطبيقك في &quot;مربّع البحث السريع&quot; من خلال فتح العناصر القابلة للبحث، والتي تقع في الإعدادات > البحث، وتفعيل تطبيقك كعنصر قابل للبحث.

يتضمّن كل تطبيق متاح في &quot;مربّع البحث السريع&quot; إدخالاً في صفحة إعدادات العناصر القابلة للبحث. يتضمّن الإدخال اسم التطبيق ووصفًا موجزًا للمحتوى الذي يمكن البحث عنه من التطبيق والذي يتم توفيره كعناصر مقترَحة في &quot;مربّع البحث السريع&quot;. لتحديد نص الوصف الخاص بتطبيقك القابل للبحث، أضِف السمة android:searchSettingsDescription إلى إعدادات البحث، كما هو موضّح في المثال التالي:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_label"
    android:hint="@string/search_hint"
    android:searchSuggestAuthority="com.example.MyCustomSuggestionProvider"
    android:searchSuggestIntentAction="android.intent.action.VIEW"
    android:includeInGlobalSearch="true"
    android:searchSettingsDescription="@string/search_description" >
</searchable>

يجب أن تكون السلسلة الخاصة بـ android:searchSettingsDescription موجزة قدر الإمكان وأن توضّح المحتوى الذي يمكن البحث عنه. على سبيل المثال، "الفنانون والألبومات والأغاني" لتطبيق موسيقى، أو "الملاحظات المحفوظة" لتطبيق دفتر ملاحظات. من المهم تقديم هذا الوصف ليعرف المستخدم نوع الاقتراحات المقدَّمة. يجب تضمين هذه السمة دائمًا عندما تكون قيمة android:includeInGlobalSearch هي &quot;صحيح&quot;.

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

إدارة اختصارات اقتراحات "مربّع البحث السريع"

يمكن تحويل الاقتراحات التي يختارها المستخدم من &quot;مربّع البحث السريع&quot; إلى اختصارات تلقائيًا. هذه اقتراحات ينسخها النظام من مقدّم المحتوى الخاص بك ليتمكّن من الوصول إليها بسرعة بدون الحاجة إلى إعادة طلبها من مقدّم المحتوى.

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

  • اجعل &quot;مربّع البحث السريع&quot; يعيد طلب المحتوى من موفّر المحتوى للحصول على نسخة جديدة من اختصار الاقتراح.

    أدخِل قيمة في العمود SUGGEST_COLUMN_SHORTCUT_ID ليتم إعادة طلب الاقتراح للحصول على نسخة جديدة في كل مرة يتم فيها عرض الاختصار. يظهر الاختصار بسرعة مع أي بيانات متوفّرة مؤخرًا إلى أن يتم عرض نتائج طلب إعادة التحميل، وعندها يتم إعادة تحميل الاقتراح بالمعلومات الجديدة. يتم إرسال طلب البحث الخاص بالتحديث إلى موفّر المحتوى مع مسار معرّف الموارد المنتظم SUGGEST_URI_PATH_SHORTCUT بدلاً من SUGGEST_URI_PATH_QUERY.

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

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

  • منع نسخ الاقتراح إلى اختصار على الإطلاق

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

  • السماح بتطبيق سلوك الاختصار التلقائي

    اترك الحقل SUGGEST_COLUMN_SHORTCUT_ID فارغًا لكل اقتراح لا يتغيّر ويمكن حفظه كاختصار.

إذا لم تتغيّر أي من اقتراحاتك أبدًا، لن تحتاج إلى العمود SUGGEST_COLUMN_SHORTCUT_ID.

لمحة عن ترتيب الاقتراحات في "مربّع البحث السريع"

بعد إتاحة اقتراحات البحث في تطبيقك لميزة &quot;مربّع البحث السريع&quot;، يحدّد ترتيب &quot;مربّع البحث السريع&quot; طريقة عرض الاقتراحات للمستخدم عند إدخال طلب بحث معيّن. وقد يعتمد ذلك على عدد التطبيقات الأخرى التي تعرض نتائج بحث عن طلب البحث هذا وعدد المرات التي يختار فيها المستخدم نتائجك مقارنةً بنتائج التطبيقات الأخرى. لا يوجد ضمان بشأن ترتيب اقتراحاتك أو ما إذا كانت اقتراحات تطبيقك ستظهر على الإطلاق لطلب بحث معيّن. بشكل عام، يؤدي تقديم نتائج عالية الجودة إلى زيادة احتمالية عرض اقتراحات تطبيقك في موضع بارز، بينما من المرجّح أن يتم ترتيب التطبيقات التي تقدّم اقتراحات منخفضة الجودة في مرتبة أدنى أو عدم عرضها.