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

عند استخدام مربّع حوار بحث 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
    

    السلوك الافتراضي هو أن يمرر النظام عنوان URI هذا وإلحاق نص الاستعلام به:

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

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

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

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

يمكن للنظام أن يرسل إليك نص طلب البحث بطريقتين. الطريقة التلقائية هي تضمين نص طلب البحث باعتباره المسار الأخير من معرّف الموارد المنتظم للمحتوى الذي تم تمريره في المعلَمة 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 باعتبارها طلب البحث. وعند تمريرها إلى طريقة SQLitequery() كوسيطاتها المعنيّة، يتم توليفها معًا، أي يتم استبدال علامة الاستفهام بنص طلب البحث. إذا تلقّيت طلبات بحث مقترَحة بهذه الطريقة وتحتاج إلى إضافة أحرف بدل إلى نص طلب البحث، ألحِقها أو ابدأها بالمَعلمة 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 يحتوي على هذا العمود، يتم تقديم كل الاقتراحات بتنسيق icon-plus-text مع الرمز الظاهر على الجانب الأيسر من الصفحة. ويمكن أن تكون القيمة فارغة أو صفرًا للإشارة إلى عدم توفّر أي رمز في هذا الصف.
SUGGEST_COLUMN_INTENT_ACTION
سلسلة إجراءات مستندة إلى الهدف إذا كان هذا العمود متوفرًا ويحتوي على قيمة في الصف المحدّد، سيتم استخدام الإجراء المحدّد هنا عند إنشاء الغرض من الاقتراح. في حال عدم توفير العنصر، يتم اتّخاذ الإجراء من الحقل android:searchSuggestIntentAction في الإعدادات التي يمكن البحث فيها. إذا كان الإجراء هو نفسه لكل الاقتراحات، من الأفضل تحديد الإجراء باستخدام android:searchSuggestIntentAction وحذف هذا العمود.
SUGGEST_COLUMN_INTENT_DATA
سلسلة معرّف الموارد المنتظم (URI) للبيانات. إذا كان هذا العمود متوفرًا ويحتوي على قيمة في الصف المحدّد، يتم استخدام هذه البيانات عند إنشاء الغرض من الاقتراح. في حال عدم توفير العنصر، يتم الحصول على البيانات من الحقل android:searchSuggestIntentData في الإعدادات القابلة للبحث. وإذا لم يتم تقديم أي مصدر، سيكون حقل بيانات الغرض خاليًا. إذا كانت بياناتك متطابقة في جميع الاقتراحات، أو يمكن وصفها باستخدام جزء ثابت ورقم تعريف محدّد، من الأفضل تحديدها باستخدام android:searchSuggestIntentData وحذف هذا العمود.
SUGGEST_COLUMN_INTENT_DATA_ID
سلسلة مسار معرّف الموارد المنتظم (URI) وفي حال توفُّر هذا العمود ويتضمّن قيمة في الصف المحدّد، سيتم إلحاق "/" بهذه القيمة بحقل البيانات في الغرض. لا تستخدم هذه السمة إلا إذا كان حقل البيانات المحدّد في السمة android:searchSuggestIntentData في الإعدادات التي يمكن البحث فيها مضبوطًا على سلسلة أساسية مناسبة.
SUGGEST_COLUMN_INTENT_EXTRA_DATA
بيانات عشوائية إذا كان هذا العمود متوفرًا ويحتوي على قيمة في صف معيّن، تكون هذه هي البيانات الإضافية المستخدمة عند تحديد الغرض من الاقتراح. إذا لم يتم توفيره، يكون حقل البيانات الإضافية للغرض فارغًا. يتيح هذا العمود للاقتراحات تقديم بيانات إضافية يتم تضمينها كقيمة إضافية في مفتاح EXTRA_DATA_KEY للقصد.
SUGGEST_COLUMN_QUERY
إذا كان هذا العمود متوفرًا وكان هذا العنصر متوفرًا في الصف المحدّد، يتم استخدام هذه البيانات عند إنشاء طلب البحث للاقتراح، ويتم تضمينها كقيمة إضافية في مفتاح QUERY الخاص بالهدف. هذا الإجراء مطلوب إذا كان الإجراء المقترَح ACTION_SEARCH، ولكنه اختياري في الحالات الأخرى.
SUGGEST_COLUMN_SHORTCUT_ID
يُستخدم هذا الخيار فقط عند تقديم اقتراحات لمربّع البحث السريع. ويشير هذا العمود إلى ما إذا كان يجب تخزين اقتراح البحث كاختصار وما إذا كان يجب التحقّق من صحته. يتم إنشاء الاختصارات عادةً عندما ينقر المستخدم على اقتراح من "مربع البحث السريع". وفي حال عدم توفّر النتيجة، يتم تخزينها كاختصار، ولا تتم إعادة تحميلها مطلقًا. وفي حال ضبطها على SUGGEST_NEVER_MAKE_SHORTCUT، لا يتم تخزين النتيجة كاختصار. وبخلاف ذلك، يتم استخدام رقم تعريف الاختصار للتحقق مرة أخرى من وجود اقتراح حديث باستخدام SUGGEST_URI_PATH_SHORTCUT.
SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING
يُستخدم هذا الخيار فقط عند تقديم اقتراحات لمربّع البحث السريع. يحدّد هذا العمود أنه يجب عرض مؤشر سريان العمل بدلاً من رمز من SUGGEST_COLUMN_ICON_2 بينما تتم إعادة تحميل اختصار هذا الاقتراح في مربّع البحث السريع.

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

تحديد الغرض من الاقتراحات

عندما يختار المستخدم اقتراحًا من القائمة التي تظهر أسفل مربّع حوار البحث أو التطبيق المصغّر، يرسل النظام عنصر 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().

  • يمكنك تقسيم معرّف الموارد المنتظم (URI) للبيانات إلى جزأين: الجزء المشترك لكل الاقتراحات والجزء الفريد لكل اقتراح. ويمكنك وضع هذه الأجزاء في السمة 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، وهو ما يطبّقه نشاطك القابل للبحث. إليك مثال على كيفية التعامل مع الأهداف أثناء استدعاء 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. بعد ذلك، يتم تمرير معرّف الموارد المنتظم (URI) إلى طريقة showResult() المحلية التي تطلب البحث من مزوّد المحتوى عن العنصر المحدّد من خلال معرّف الموارد المنتظم (URI).

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

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

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

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

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

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

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

<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". يمنح ذلك إمكانية الوصول إلى "مربع البحث السريع" حتى يتمكن من الاستعلام من موفّر المحتوى عن الاقتراحات.

وإذا لم يكن موفر المحتوى يفرض أذونات القراءة، يقرأ مربع البحث السريع هذه الأذونات بشكل تلقائي.

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

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

لكل تطبيق متاح لمربع البحث السريع إدخال في صفحة إعدادات العناصر القابلة للبحث. يشمل الإدخال اسم التطبيق ووصفًا موجزًا للمحتوى الذي يمكن البحث عنه من التطبيق وإتاحته للاقتراحات في مربع البحث السريع. لتحديد نص الوصف لتطبيقك القابل للبحث، أضِف السمة 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 true.

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

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

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

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

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

    أدخِل قيمة في عمود SUGGEST_COLUMN_SHORTCUT_ID للاقتراح الذي ستتم إعادة طلبه للحصول على نسخة جديدة في كل مرة يتم فيها عرض الاختصار. يظهر الاختصار بسرعة مع آخر البيانات المتاحة إلى أن يتم عرض طلب إعادة التحميل، وعندها تتم إعادة تحميل الاقتراح بالمعلومات الجديدة. يتم إرسال طلب إعادة التحميل إلى موفّر المحتوى باستخدام مسار معرّف الموارد المنتظم (URI) 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.

معلومات عن ترتيب اقتراحات "مربع البحث السريع"

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