پیشنهادات جستجوی سفارشی را اضافه کنید

روش نوشتن را امتحان کنید
Jetpack Compose ابزار رابط کاربری پیشنهادی برای اندروید است. یاد بگیرید که چگونه قابلیت جستجو را در Compose اضافه کنید.

هنگام استفاده از کادر محاوره‌ای جستجوی اندروید یا ویجت جستجو، می‌توانید پیشنهادهای جستجوی سفارشی ارائه دهید که از داده‌های برنامه شما ایجاد می‌شوند. به عنوان مثال، اگر برنامه شما یک فرهنگ لغت است، می‌توانید قبل از اینکه کاربر عبارت مورد نظر خود را وارد کند، کلماتی را از فرهنگ لغت پیشنهاد دهید که با متن وارد شده در فیلد جستجو مطابقت داشته باشند. این پیشنهادها ارزشمند هستند زیرا می‌توانند به طور موثر آنچه کاربر می‌خواهد را پیش‌بینی کرده و دسترسی فوری به آن را فراهم کنند. شکل 1 نمونه‌ای از یک کادر محاوره‌ای جستجو با پیشنهادهای سفارشی را نشان می‌دهد.

پس از ارائه پیشنهادات سفارشی، می‌توانید آنها را در کادر جستجوی سریع در سراسر سیستم نیز در دسترس قرار دهید و از خارج از برنامه خود به محتوای خود دسترسی پیدا کنید.

قبل از افزودن پیشنهادهای سفارشی، کادر محاوره‌ای جستجوی اندروید یا یک ویجت جستجو برای جستجوها را در برنامه خود پیاده‌سازی کنید. به بخش ایجاد رابط جستجو و ارائه دهندگان محتوا مراجعه کنید.

اصول اولیه

شکل ۱. تصویری از پنجره‌ی جستجو با پیشنهادهای جستجوی سفارشی.

وقتی کاربر یک پیشنهاد سفارشی را انتخاب می‌کند، سیستم یک Intent به activity قابل جستجوی شما ارسال می‌کند. برخلاف یک کوئری جستجوی معمولی که یک Intent را با اکشن ACTION_SEARCH ارسال می‌کند، می‌توانید پیشنهادهای سفارشی خود را طوری تعریف کنید که از ACTION_VIEW یا هر اکشن Intent دیگری استفاده کنند و همچنین داده‌هایی را که مربوط به پیشنهاد انتخاب شده هستند، در آن بگنجانید. در مثال فرهنگ لغت، وقتی کاربر یک پیشنهاد را انتخاب می‌کند، برنامه می‌تواند بلافاصله تعریف آن کلمه را باز کند، به جای اینکه در فرهنگ لغت به دنبال موارد منطبق بگردد.

برای ارائه پیشنهادات سفارشی، مراحل زیر را انجام دهید:

  • یک فعالیت جستجوی پایه، همانطور که در «ایجاد رابط جستجو» توضیح داده شده است، پیاده‌سازی کنید.
  • پیکربندی قابل جستجو را با اطلاعات مربوط به ارائه دهنده محتوایی که پیشنهادات سفارشی ارائه می‌دهد، اصلاح کنید.
  • برای پیشنهادات خود، یک جدول، مانند SQLiteDatabase ، بسازید و جدول را با ستون‌های مورد نیاز قالب‌بندی کنید.
  • یک ارائه‌دهنده محتوا ایجاد کنید که به جدول پیشنهادات شما دسترسی داشته باشد و ارائه‌دهنده را در مانیفست خود اعلام کنید.
  • نوع Intent که هنگام انتخاب یک پیشنهاد توسط کاربر، شامل یک اقدام سفارشی و داده سفارشی، ارسال می‌شود را مشخص کنید.

همانطور که سیستم اندروید کادر محاوره‌ای جستجو را نمایش می‌دهد، پیشنهادات جستجوی شما را نیز نمایش می‌دهد. شما به یک ارائه‌دهنده محتوا نیاز دارید که سیستم بتواند پیشنهادات شما را از آن بازیابی کند. برای یادگیری نحوه ایجاد یک ارائه‌دهنده محتوا، بخش ارائه‌دهندگان محتوا را مطالعه کنید.

وقتی سیستم تشخیص می‌دهد که فعالیت شما قابل جستجو است و پیشنهادات جستجو ارائه می‌دهد، هنگام وارد کردن یک پرس‌وجو توسط کاربر، مراحل زیر انجام می‌شود:

  1. سیستم متن عبارت جستجو - یعنی هر آنچه تاکنون وارد شده است - را دریافت می‌کند و یک پرس و جو برای ارائه دهنده محتوای شما که پیشنهادات شما را مدیریت می‌کند، انجام می‌دهد.
  2. ارائه دهنده محتوای شما یک Cursor برمی‌گرداند که به تمام پیشنهاداتی که مربوط به متن عبارت جستجو شده هستند اشاره می‌کند.
  3. سیستم فهرستی از پیشنهادهای ارائه شده توسط Cursor را نمایش می‌دهد.

پس از نمایش پیشنهادات سفارشی، ممکن است موارد زیر اتفاق بیفتد:

  • اگر کاربر حرف دیگری وارد کند یا به هر نحوی عبارت جستجو را تغییر دهد، مراحل قبلی تکرار می‌شوند و لیست پیشنهادات بر اساس آن به‌روزرسانی می‌شود.
  • اگر کاربر جستجو را انجام دهد، پیشنهادات نادیده گرفته می‌شوند و جستجو با استفاده از هدف معمول ACTION_SEARCH به فعالیت قابل جستجوی شما تحویل داده می‌شود.
  • اگر کاربر پیشنهادی را انتخاب کند، یک اینتنت به اکتیویتی قابل جستجوی شما ارسال می‌شود که شامل یک اقدام سفارشی و داده‌های سفارشی است تا برنامه شما بتواند محتوای پیشنهادی را باز کند.

تغییر پیکربندی قابل جستجو

برای افزودن پشتیبانی از پیشنهادهای سفارشی، ویژگی android:searchSuggestAuthority را به عنصر <searchable> در فایل پیکربندی 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 فقط در صورتی در URI گنجانده می‌شود که چنین مسیری را در فایل پیکربندی قابل جستجو با ویژگی android:searchSuggestPath تنظیم کرده باشید. این مورد فقط در صورتی ضروری است که از یک ارائه‌دهنده محتوای یکسان برای چندین فعالیت قابل جستجو استفاده کنید. در این صورت، منبع پرس‌وجوی پیشنهادی را ابهام‌زدایی کنید.

  2. projection
    همیشه تهی.
  3. selection
    مقداری که در ویژگی android:searchSuggestSelection از فایل پیکربندی قابل جستجوی شما ارائه شده است، یا اگر ویژگی android:searchSuggestSelection را تعریف نکرده باشید، null خواهد بود. بخش بعدی این موضوع را بیشتر مورد بحث قرار می‌دهد.
  4. selectionArgs
    اگر ویژگی android:searchSuggestSelection را در پیکربندی قابل جستجو خود تعریف کنید، عبارت جستجو را به عنوان اولین و تنها عنصر آرایه در بر می‌گیرد. اگر android:searchSuggestSelection را تعریف نکنید، این پارامتر null خواهد بود. بخش بعدی این موضوع را بیشتر مورد بحث قرار می‌دهد.
  5. sortOrder
    همیشه تهی.

سیستم می‌تواند متن جستجوی جستجو را به دو روش برای شما ارسال کند. روش پیش‌فرض این است که متن جستجو به عنوان آخرین مسیر URI محتوا که در پارامتر uri ارسال می‌شود، درج شود. با این حال، اگر یک مقدار انتخابی را در ویژگی android:searchSuggestSelection پیکربندی قابل جستجو خود قرار دهید، متن جستجو به عنوان اولین عنصر آرایه رشته‌ای selectionArgs ارسال می‌شود. این دو گزینه در ادامه توضیح داده خواهند شد.

کوئری را در Uri دریافت کنید

به طور پیش‌فرض، کوئری به عنوان آخرین بخش پارامتر uri - یک شیء Uri - اضافه می‌شود. برای بازیابی متن کوئری در این مورد، getLastPathSegment() استفاده کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

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

جاوا

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 ارسال می‌کنید، با هم ترکیب می‌شوند - به این معنی که علامت سوال با متن عبارت جستجو جایگزین می‌شود. اگر از این طریق عبارات جستجو شده پیشنهادی دریافت می‌کنید و نیاز به اضافه کردن wildcards به متن عبارت جستجو دارید، آنها را به پارامتر selectionArgs اضافه یا پیشوند کنید، زیرا این مقدار در علامت نقل قول قرار گرفته و به جای علامت سوال درج شده است.

یکی دیگر از ویژگی‌های مثال قبلی android:searchSuggestIntentAction است که اقدام intent ارسال شده با هر intent را هنگام انتخاب یک پیشنهاد توسط کاربر تعریف می‌کند. این موضوع در بخش «اعلان یک intent برای پیشنهادات» بیشتر مورد بحث قرار گرفته است.

ساخت جدول پیشنهادات

وقتی پیشنهادات را با Cursor به سیستم برمی‌گردانید، سیستم انتظار ستون‌های خاصی را در هر ردیف دارد. صرف نظر از اینکه داده‌های پیشنهاد خود را در یک پایگاه داده SQLite روی دستگاه، یک پایگاه داده روی یک سرور وب یا فرمت دیگری روی دستگاه یا وب ذخیره می‌کنید، پیشنهادات را به صورت ردیف‌هایی در یک جدول قالب‌بندی کرده و آنها را با Cursor ارائه دهید.

سیستم چندین ستون را درک می‌کند، اما فقط دو تا از آنها مورد نیاز است:

_ID
یک شناسه ردیف عدد صحیح منحصر به فرد برای هر پیشنهاد. سیستم برای ارائه پیشنهادات در ListView به این شناسه نیاز دارد.
SUGGEST_COLUMN_TEXT_1
رشته ای که به عنوان پیشنهاد ارائه شده است.

ستون‌های زیر همگی اختیاری هستند. بیشتر آنها در بخش‌های بعدی بیشتر مورد بحث قرار گرفته‌اند.

SUGGEST_COLUMN_TEXT_2
یک رشته. اگر Cursor شما شامل این ستون باشد، تمام پیشنهادات در قالب دو خطی ارائه می‌شوند. رشته موجود در این ستون به عنوان یک خط دوم و کوچکتر از متن زیر متن پیشنهاد اولیه نمایش داده می‌شود. این خط می‌تواند تهی یا خالی باشد تا نشان دهد متن ثانویه‌ای وجود ندارد.
SUGGEST_COLUMN_ICON_1
یک رشته‌ی URL منبع، محتوا یا فایل قابل ترسیم. اگر Cursor شما شامل این ستون باشد، تمام پیشنهادات در قالب آیکون به علاوه‌ی متن با آیکون قابل ترسیم در سمت چپ ارائه می‌شوند. این می‌تواند تهی یا صفر باشد تا نشان دهد هیچ آیکونی در این سطر وجود ندارد.
SUGGEST_COLUMN_ICON_2
یک رشته‌ی URL منبع، محتوا یا فایل قابل ترسیم. اگر Cursor شما شامل این ستون باشد، تمام پیشنهادات در قالب آیکون به علاوه‌ی متن با آیکون در سمت راست ارائه می‌شوند. این می‌تواند تهی یا صفر باشد تا نشان دهد هیچ آیکونی در این سطر وجود ندارد.
SUGGEST_COLUMN_INTENT_ACTION
یک رشته اکشن intent. اگر این ستون وجود داشته باشد و حاوی مقداری در ردیف داده شده باشد، اکشن تعریف شده در اینجا هنگام تشکیل intent پیشنهاد استفاده می‌شود. اگر عنصر ارائه نشده باشد، اکشن از فیلد android:searchSuggestIntentAction در پیکربندی قابل جستجو شما گرفته می‌شود. اگر اکشن شما برای همه پیشنهادات یکسان است، مشخص کردن اکشن با استفاده از android:searchSuggestIntentAction و حذف این ستون کارآمدتر است.
SUGGEST_COLUMN_INTENT_DATA
یک رشته داده URI. اگر این ستون وجود داشته باشد و حاوی مقداری در ردیف داده شده باشد، این داده‌ها هنگام تشکیل intent پیشنهاد استفاده می‌شوند. اگر عنصر ارائه نشده باشد، داده‌ها از فیلد android:searchSuggestIntentData در پیکربندی قابل جستجو شما گرفته می‌شوند. اگر هیچ منبعی ارائه نشده باشد، فیلد داده intent تهی است. اگر داده‌های شما برای همه پیشنهادات یکسان است، یا می‌توان آنها را با استفاده از یک بخش ثابت و یک شناسه خاص توصیف کرد، مشخص کردن آن با استفاده از android:searchSuggestIntentData و حذف این ستون کارآمدتر است.
SUGGEST_COLUMN_INTENT_DATA_ID
یک رشته مسیر URI. اگر این ستون وجود داشته باشد و حاوی مقداری در ردیف داده شده باشد، آنگاه "/" و این مقدار به فیلد داده در intent اضافه می‌شود. فقط در صورتی از این استفاده کنید که فیلد داده مشخص شده توسط ویژگی android:searchSuggestIntentData در پیکربندی قابل جستجو، از قبل روی یک رشته پایه مناسب تنظیم شده باشد.
SUGGEST_COLUMN_INTENT_EXTRA_DATA
داده‌های دلخواه. اگر این ستون وجود داشته باشد و حاوی مقداری در یک ردیف مشخص باشد، این داده‌های اضافی است که هنگام تشکیل intent پیشنهاد استفاده می‌شود. اگر ارائه نشود، فیلد داده‌های اضافی intent تهی است. این ستون به پیشنهادات اجازه می‌دهد داده‌های اضافی را ارائه دهند که به عنوان یک مقدار اضافی در کلید EXTRA_DATA_KEY intent گنجانده شده است.
SUGGEST_COLUMN_QUERY
اگر این ستون و این عنصر در ردیف داده شده وجود داشته باشند، این داده‌ای است که هنگام تشکیل کوئری پیشنهاد استفاده می‌شود و به عنوان یک مقدار اضافی در کلید QUERY مربوط به intent گنجانده شده است. اگر اکشن پیشنهاد ACTION_SEARCH باشد، این مورد الزامی است، اما در غیر این صورت اختیاری است.
SUGGEST_COLUMN_SHORTCUT_ID
فقط هنگام ارائه پیشنهادات برای کادر جستجوی سریع استفاده می‌شود. این ستون نشان می‌دهد که آیا یک پیشنهاد جستجو باید به عنوان میانبر ذخیره شود و آیا باید اعتبارسنجی شود. میانبرها معمولاً زمانی تشکیل می‌شوند که کاربر روی پیشنهادی از کادر جستجوی سریع ضربه می‌زند. در صورت عدم وجود، نتیجه به عنوان میانبر ذخیره شده و هرگز به‌روزرسانی نمی‌شود. اگر روی SUGGEST_NEVER_MAKE_SHORTCUT تنظیم شود، نتیجه به عنوان میانبر ذخیره نمی‌شود. در غیر این صورت، از شناسه میانبر برای بررسی مجدد پیشنهاد به‌روز با استفاده از SUGGEST_URI_PATH_SHORTCUT استفاده می‌شود.
SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING
فقط هنگام ارائه پیشنهادات برای کادر جستجوی سریع استفاده می‌شود. این ستون مشخص می‌کند که هنگام به‌روزرسانی میانبر این پیشنهاد در کادر جستجوی سریع، باید به جای آیکون SUGGEST_COLUMN_ICON_2 یک چرخنده نمایش داده شود.

بیشتر این ستون‌ها در بخش‌های بعدی بیشتر مورد بحث قرار گرفته‌اند.

اعلام هدف برای پیشنهادات

وقتی کاربر پیشنهادی را از لیستی که در زیر کادر محاوره‌ای جستجو یا ویجت ظاهر می‌شود انتخاب می‌کند، سیستم یک Intent سفارشی به activity قابل جستجوی شما ارسال می‌کند. شما باید action و data را برای intent تعریف کنید.

اقدام مورد نظر را اعلام کنید

رایج‌ترین اقدام اینتنت برای یک پیشنهاد سفارشی ACTION_VIEW است که برای زمانی که می‌خواهید چیزی مانند تعریف یک کلمه، اطلاعات تماس یک شخص یا یک صفحه وب را باز کنید، مناسب است. با این حال، اقدام اینتنت می‌تواند هر اقدام دیگری باشد و برای هر پیشنهاد می‌تواند متفاوت باشد.

بسته به اینکه آیا می‌خواهید همه پیشنهادات از یک اقدام intent یکسان استفاده کنند، می‌توانید اقدام را به دو روش تعریف کنید:

  • از ویژگی 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 و سپس پر کردن آن با داده‌های منحصر به فرد برای هر سطر، تمام اطلاعات داده‌ای لازم برای هر intent را در جدول پیشنهادات ارائه دهید. داده‌های این ستون دقیقاً همانطور که در این ستون تعریف می‌کنید، به intent متصل می‌شوند. سپس می‌توانید آن را با 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() بازیابی کنید.

اضافه کردن داده‌های بیشتر

اگر نیاز دارید اطلاعات بیشتری را با intent خود بیان کنید، می‌توانید ستون دیگری در جدول اضافه کنید، مانند SUGGEST_COLUMN_INTENT_EXTRA_DATA ، که می‌تواند اطلاعات اضافی در مورد پیشنهاد را ذخیره کند. داده‌های ذخیره شده در این ستون در EXTRA_DATA_KEY از بسته اضافی intent قرار می‌گیرند.

قصد را مدیریت کنید

پس از اینکه پیشنهادات جستجوی سفارشی را با intentهای سفارشی ارائه دادید، به activity قابل جستجوی خود نیاز دارید تا این intentها را هنگام انتخاب یک پیشنهاد توسط کاربر مدیریت کند. این علاوه بر مدیریت intent مربوط به ACTION_SEARCH است که activity قابل جستجوی شما از قبل آن را انجام می‌دهد. در اینجا مثالی از نحوه مدیریت intentها در طول فراخوانی onCreate() activity شما آورده شده است:

کاتلین

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

جاوا

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

در این مثال، اکشن intent، ACTION_VIEW است و داده‌ها یک URI کامل را که به آیتم پیشنهادی اشاره می‌کند، حمل می‌کنند، همانطور که توسط رشته android:searchSuggestIntentData و ستون SUGGEST_COLUMN_INTENT_DATA_ID سنتز شده است. سپس URI به متد محلی showResult() ارسال می‌شود که از ارائه‌دهنده محتوا برای آیتم مشخص شده توسط URI پرس و جو می‌کند.

متن درخواست را بازنویسی کنید

به طور پیش‌فرض، اگر کاربر با استفاده از کنترل‌های جهت‌دار، مانند ترک‌بال یا D-pad، در لیست پیشنهادات حرکت کند، متن جستجو به‌روزرسانی نمی‌شود. با این حال، می‌توانید متن جستجوی کاربر را همانطور که در کادر متن ظاهر می‌شود، به طور موقت با جستجویی که با پیشنهاد در فوکوس مطابقت دارد، بازنویسی کنید. این به کاربر اجازه می‌دهد تا جستجوی پیشنهادی را ببیند و بتواند کادر جستجو را انتخاب کرده و قبل از ارسال آن به عنوان جستجو، جستجو را ویرایش کند.

شما می‌توانید متن پرس‌وجو را به روش‌های زیر بازنویسی کنید:

  • ویژگی android:searchMode را به پیکربندی قابل جستجوی خود با مقدار "queryRewriteFromText" اضافه کنید. در این حالت، محتوای ستون SUGGEST_COLUMN_TEXT_1 پیشنهاد برای بازنویسی متن جستجو استفاده می‌شود.
  • ویژگی android:searchMode را به پیکربندی searchable\ خود با مقدار "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" این محدودیت را اصلاح می‌کند. این امر دسترسی به کادر جستجوی سریع را فراهم می‌کند تا بتواند از ارائه‌دهنده محتوای شما برای پیشنهادات پرس‌وجو کند.

اگر ارائه دهنده محتوای شما مجوزهای خواندن را اعمال نکند، کادر جستجوی سریع به طور پیش فرض آن را می‌خواند.

فعال کردن پیشنهادات در دستگاه

به‌طور پیش‌فرض، برنامه‌ها نمی‌توانند در کادر جستجوی سریع پیشنهاد ارائه دهند، حتی اگر برای این کار پیکربندی شده باشند. کاربر با باز کردن موارد قابل جستجو - واقع در تنظیمات > جستجو - و فعال کردن برنامه خود به‌عنوان یک مورد قابل جستجو، انتخاب می‌کند که آیا پیشنهادهای برنامه شما در کادر جستجوی سریع گنجانده شود یا خیر.

هر برنامه‌ای که در کادر جستجوی سریع (Quick Search Box) در دسترس است، یک ورودی در صفحه تنظیمات موارد قابل جستجو (Searchable items) دارد. این ورودی شامل نام برنامه و توضیح کوتاهی از محتوایی است که از برنامه قابل جستجو است و برای پیشنهاد در کادر جستجوی سریع در دسترس قرار می‌گیرد. برای تعریف متن توضیح برای برنامه قابل جستجوی خود، ویژگی 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 را نیز به جدول پیشنهادات خود با مقدار true اضافه کنید تا یک نشانگر پیشرفت برای آیکون سمت راست تا زمان تکمیل به‌روزرسانی نمایش داده شود. هر مقداری غیر از true نشانگر پیشرفت را نشان نمی‌دهد.

  • از کپی شدن پیشنهاد در یک میانبر به طور کلی جلوگیری کنید.

    مقدار SUGGEST_NEVER_MAKE_SHORTCUT را در ستون SUGGEST_COLUMN_SHORTCUT_ID وارد کنید. در این حالت، پیشنهاد هرگز در یک میانبر کپی نمی‌شود. این کار فقط در صورتی ضروری است که مطلقاً نمی‌خواهید پیشنهاد کپی‌شده قبلی ظاهر شود. اگر مقدار عادی برای ستون وارد کنید، میانبر پیشنهاد فقط تا زمانی که کوئری refresh برگردد، ظاهر می‌شود.

  • بگذارید رفتار میانبر پیش‌فرض اعمال شود.

    برای هر پیشنهادی که تغییر نمی‌کند و می‌توان آن را به عنوان میانبر ذخیره کرد، SUGGEST_COLUMN_SHORTCUT_ID خالی بگذارید.

اگر هیچ یک از پیشنهادات شما تغییر نکرد، پس به ستون SUGGEST_COLUMN_SHORTCUT_ID نیازی ندارید.

درباره رتبه‌بندی پیشنهادی جعبه جستجوی سریع

وقتی پیشنهادات جستجوی برنامه خود را در کادر جستجوی سریع قرار می‌دهید، رتبه‌بندی کادر جستجوی سریع تعیین می‌کند که چگونه پیشنهادات برای یک عبارت خاص به کاربر نمایش داده شوند. این ممکن است به این بستگی داشته باشد که چند برنامه دیگر برای آن عبارت نتیجه دارند و کاربر در مقایسه با نتایج سایر برنامه‌ها، چند بار نتایج شما را انتخاب می‌کند. هیچ تضمینی در مورد نحوه رتبه‌بندی پیشنهادات شما یا اینکه آیا پیشنهادات برنامه شما برای یک عبارت خاص نمایش داده می‌شود یا خیر، وجود ندارد. به طور کلی، ارائه نتایج با کیفیت، احتمال ارائه پیشنهادات برنامه شما را در موقعیت برجسته افزایش می‌دهد و برنامه‌هایی که پیشنهادات بی‌کیفیت ارائه می‌دهند، احتمال بیشتری دارد که در رتبه پایین‌تری قرار بگیرند یا نمایش داده نشوند.