Khi sử dụng hộp thoại tìm kiếm hoặc tiện ích tìm kiếm của Android, bạn có thể cung cấp các đề xuất tìm kiếm tuỳ chỉnh được tạo từ dữ liệu trong ứng dụng của mình. Ví dụ: nếu ứng dụng của bạn là một từ điển, bạn có thể đề xuất các từ trong từ điển trùng khớp với văn bản được nhập vào trường tìm kiếm trước khi người dùng hoàn tất việc nhập cụm từ tìm kiếm. Những đề xuất này rất có giá trị vì chúng có thể dự đoán hiệu quả những gì người dùng muốn và cung cấp quyền truy cập tức thì vào nội dung đó. Hình 1 minh hoạ ví dụ về hộp thoại tìm kiếm có các đề xuất tuỳ chỉnh.
Sau khi cung cấp các đề xuất tuỳ chỉnh, bạn cũng có thể cung cấp các đề xuất đó cho Hộp tìm kiếm nhanh trên toàn hệ thống, cho phép truy cập vào nội dung của bạn từ bên ngoài ứng dụng.
Trước khi thêm đề xuất tuỳ chỉnh, hãy triển khai hộp thoại tìm kiếm Android hoặc một tiện ích tìm kiếm cho các lượt tìm kiếm trong ứng dụng của bạn. Hãy xem phần Tạo giao diện tìm kiếm và Trình cung cấp nội dung.
Thông tin cơ bản

Hình 1. Ảnh chụp màn hình về một hộp thoại tìm kiếm có các cụm từ tìm kiếm được đề xuất tuỳ chỉnh.
Khi người dùng chọn một đề xuất tuỳ chỉnh, hệ thống sẽ gửi một Intent
đến hoạt động có thể tìm kiếm của bạn. Không giống như một cụm từ tìm kiếm thông thường gửi ý định bằng thao tác ACTION_SEARCH
, bạn có thể xác định các đề xuất tuỳ chỉnh để sử dụng ACTION_VIEW
(hoặc bất kỳ thao tác ý định nào khác) và cũng bao gồm dữ liệu có liên quan đến đề xuất đã chọn. Trong ví dụ về từ điển, khi người dùng chọn một đề xuất, ứng dụng có thể mở ngay định nghĩa cho từ đó thay vì tìm kiếm các kết quả trùng khớp trong từ điển.
Để cung cấp đề xuất tuỳ chỉnh, hãy thực hiện các bước sau:
- Triển khai một hoạt động cơ bản có thể tìm kiếm, như mô tả trong phần Tạo giao diện tìm kiếm.
- Sửa đổi cấu hình có thể tìm kiếm bằng thông tin về nhà cung cấp nội dung cung cấp các đề xuất tuỳ chỉnh.
- Tạo một bảng (chẳng hạn như trong
SQLiteDatabase
) cho các đề xuất của bạn và định dạng bảng bằng các cột bắt buộc. - Tạo một trình cung cấp nội dung có quyền truy cập vào bảng đề xuất của bạn và khai báo trình cung cấp đó trong tệp kê khai.
- Khai báo loại
Intent
sẽ được gửi khi người dùng chọn một đề xuất, bao gồm cả thao tác tuỳ chỉnh và dữ liệu tuỳ chỉnh.
Tương tự như khi hệ thống Android hiển thị hộp thoại tìm kiếm, hệ thống cũng hiển thị các đề xuất tìm kiếm của bạn. Bạn cần một trình cung cấp nội dung mà hệ thống có thể truy xuất các đề xuất của bạn. Đọc phần Trình cung cấp nội dung để tìm hiểu cách tạo trình cung cấp nội dung.
Khi hệ thống xác định rằng hoạt động của bạn có thể tìm kiếm và đưa ra các đề xuất tìm kiếm, quy trình sau đây sẽ diễn ra khi người dùng nhập một cụm từ tìm kiếm:
- Hệ thống sẽ lấy văn bản của cụm từ tìm kiếm (tức là bất kỳ nội dung nào đã được nhập cho đến thời điểm này) và thực hiện một truy vấn đến trình cung cấp nội dung quản lý các đề xuất của bạn.
- Nhà cung cấp nội dung của bạn trả về một
Cursor
trỏ đến tất cả các đề xuất có liên quan đến văn bản cụm từ tìm kiếm. - Hệ thống sẽ hiển thị danh sách các đề xuất do
Cursor
cung cấp.
Sau khi các đề xuất tuỳ chỉnh xuất hiện, có thể xảy ra những trường hợp sau:
- Nếu người dùng nhập một chữ cái khác hoặc thay đổi cụm từ tìm kiếm theo bất kỳ cách nào, các bước trước đó sẽ lặp lại và danh sách đề xuất sẽ cập nhật cho phù hợp.
- Nếu người dùng thực hiện tìm kiếm, các đề xuất sẽ bị bỏ qua và cụm từ tìm kiếm sẽ được gửi đến hoạt động có thể tìm kiếm của bạn bằng ý định
ACTION_SEARCH
thông thường. - Nếu người dùng chọn một đề xuất, thì một ý định sẽ được gửi đến hoạt động có thể tìm kiếm của bạn, mang theo một thao tác tuỳ chỉnh và dữ liệu tuỳ chỉnh để ứng dụng của bạn có thể mở nội dung được đề xuất.
Sửa đổi cấu hình có thể tìm kiếm
Để thêm tính năng hỗ trợ các đề xuất tuỳ chỉnh, hãy thêm thuộc tính android:searchSuggestAuthority
vào phần tử <searchable>
trong tệp cấu hình có thể tìm kiếm, như trong ví dụ sau:
<?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>
Bạn có thể cần thêm các thuộc tính, tuỳ thuộc vào loại ý định mà bạn đính kèm vào từng đề xuất và cách bạn muốn định dạng các truy vấn cho trình cung cấp nội dung. Các thuộc tính không bắt buộc khác sẽ được thảo luận trong các phần sau.
Tạo một trình cung cấp nội dung
Để tạo một trình cung cấp nội dung cho các đề xuất tuỳ chỉnh, trước tiên, hãy xem phần Trình cung cấp nội dung để tìm hiểu cách tạo một trình cung cấp nội dung. Trình cung cấp nội dung cho các đề xuất tuỳ chỉnh cũng tương tự như mọi trình cung cấp nội dung khác. Tuy nhiên, đối với mỗi đề xuất mà bạn cung cấp, hàng tương ứng trong Cursor
phải bao gồm các cột cụ thể mà hệ thống hiểu và sử dụng để định dạng các đề xuất.
Khi người dùng nhập văn bản vào hộp thoại tìm kiếm hoặc tiện ích tìm kiếm, hệ thống sẽ truy vấn nhà cung cấp nội dung của bạn để tìm các đề xuất bằng cách gọi query()
mỗi khi người dùng nhập một chữ cái. Khi triển khai query()
, nhà cung cấp nội dung của bạn phải tìm kiếm dữ liệu đề xuất và trả về một Cursor
trỏ đến các hàng mà nhà cung cấp nội dung xác định là đề xuất phù hợp.
Thông tin chi tiết về cách tạo trình cung cấp nội dung cho các đề xuất tuỳ chỉnh sẽ được thảo luận trong 2 phần sau:
- Xử lý truy vấn đề xuất
- Cách hệ thống gửi yêu cầu đến nhà cung cấp nội dung của bạn và cách xử lý các yêu cầu đó.
- Tạo bảng đề xuất
- Cách xác định các cột mà hệ thống mong đợi trong
Cursor
được trả về theo từng truy vấn.
Xử lý truy vấn đề xuất
Khi yêu cầu đề xuất từ trình cung cấp nội dung của bạn, hệ thống sẽ gọi phương thức query()
của trình cung cấp nội dung. Triển khai phương thức này để tìm kiếm dữ liệu đề xuất và trả về một Cursor
trỏ đến những đề xuất mà bạn cho là phù hợp.
Sau đây là thông tin tóm tắt về các tham số mà hệ thống truyền đến phương thức query()
của bạn, được liệt kê theo thứ tự:
uri
Luôn là một nội dung
Uri
, được định dạng như sau:content://your.authority/optional.suggest.path/
SUGGEST_URI_PATH_QUERY
Hành vi mặc định là hệ thống sẽ truyền URI này và thêm văn bản truy vấn vào đó:
content://your.authority/optional.suggest.path/
SUGGEST_URI_PATH_QUERY
/puppiesVăn bản truy vấn ở cuối được mã hoá bằng các quy tắc mã hoá URI, vì vậy, bạn có thể cần phải giải mã văn bản đó trước khi thực hiện tìm kiếm.
Phần
optional.suggest.path
chỉ được đưa vào URI nếu bạn đặt đường dẫn như vậy trong tệp cấu hình có thể tìm kiếm bằng thuộc tínhandroid:searchSuggestPath
. Bạn chỉ cần cung cấp thuộc tính này nếu sử dụng cùng một trình cung cấp nội dung cho nhiều hoạt động có thể tìm kiếm. Nếu đây là trường hợp này, hãy phân biệt nguồn của truy vấn đề xuất.projection
- Luôn rỗng.
selection
- Giá trị được cung cấp trong thuộc tính
android:searchSuggestSelection
của tệp cấu hình có thể tìm kiếm hoặc giá trị rỗng nếu bạn không khai báo thuộc tínhandroid:searchSuggestSelection
. Phần tiếp theo sẽ thảo luận thêm về vấn đề này.selectionArgs
- Chứa cụm từ tìm kiếm dưới dạng phần tử đầu tiên và duy nhất của mảng nếu bạn khai báo thuộc tính
android:searchSuggestSelection
trong cấu hình có thể tìm kiếm. Nếu bạn không khai báoandroid:searchSuggestSelection
, thì tham số này sẽ là rỗng. Phần tiếp theo sẽ thảo luận thêm về vấn đề này.sortOrder
- Luôn rỗng.
Hệ thống có thể gửi cho bạn văn bản cụm từ tìm kiếm theo hai cách. Cách mặc định là văn bản truy vấn được đưa vào làm đường dẫn cuối cùng của URI nội dung được truyền trong tham số uri
. Tuy nhiên, nếu bạn thêm một giá trị lựa chọn vào thuộc tính android:searchSuggestSelection
trong cấu hình có thể tìm kiếm, thì văn bản truy vấn sẽ được truyền dưới dạng phần tử đầu tiên của mảng chuỗi selectionArgs
. Hai lựa chọn này sẽ được mô tả ở phần tiếp theo.
Lấy truy vấn trong Uri
Theo mặc định, truy vấn được thêm dưới dạng phân đoạn cuối cùng của tham số uri
– một đối tượng Uri
. Để truy xuất văn bản truy vấn trong trường hợp này, hãy sử dụng getLastPathSegment()
, như minh hoạ trong ví dụ sau:
Kotlin
val query: String = uri.lastPathSegment.toLowerCase()
Java
String query = uri.getLastPathSegment().toLowerCase();
Thao tác này trả về phân đoạn cuối cùng của Uri
, đó là văn bản truy vấn mà người dùng nhập.
Lấy truy vấn trong các đối số lựa chọn
Thay vì sử dụng URI, có thể sẽ hợp lý hơn nếu phương thức query()
của bạn nhận được mọi thứ cần thiết để thực hiện tra cứu và bạn có thể muốn các tham số selection
và selectionArgs
mang các giá trị thích hợp. Trong trường hợp này, hãy thêm thuộc tính android:searchSuggestSelection
vào cấu hình có thể tìm kiếm bằng chuỗi lựa chọn SQLite. Trong chuỗi lựa chọn, hãy thêm dấu chấm hỏi (?) làm trình giữ chỗ cho cụm từ tìm kiếm thực tế. Hệ thống gọi query()
bằng chuỗi lựa chọn làm tham số selection
và cụm từ tìm kiếm làm phần tử đầu tiên trong mảng selectionArgs
.
Ví dụ: sau đây là cách bạn có thể tạo thuộc tính android:searchSuggestSelection
để tạo một câu lệnh tìm kiếm toàn văn:
<?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>
Với cấu hình này, phương thức query()
của bạn sẽ phân phối tham số selection
dưới dạng "word MATCH ?"
và tham số selectionArgs
dưới dạng cụm từ tìm kiếm. Khi bạn truyền các đối số này đến một phương thức query()
SQLite, các đối số này sẽ được tổng hợp với nhau, tức là dấu hỏi sẽ được thay thế bằng văn bản truy vấn. Nếu bạn nhận được các cụm từ tìm kiếm đề xuất theo cách này và cần thêm ký tự đại diện vào văn bản cụm từ tìm kiếm, hãy thêm hoặc đặt tiền tố cho các ký tự đó vào tham số selectionArgs
, vì giá trị này được đặt trong dấu ngoặc kép và được chèn thay cho dấu chấm hỏi.
Một thuộc tính khác trong ví dụ trước là android:searchSuggestIntentAction
, xác định thao tác theo ý định được gửi cùng với mỗi ý định khi người dùng chọn một đề xuất. Vấn đề này sẽ được thảo luận thêm trong phần Khai báo ý định cho các đề xuất.
Tạo bảng đề xuất
Khi bạn trả về các đề xuất cho hệ thống bằng Cursor
, hệ thống sẽ yêu cầu các cột cụ thể trong mỗi hàng. Bất kể bạn lưu trữ dữ liệu đề xuất trong cơ sở dữ liệu SQLite trên thiết bị, cơ sở dữ liệu trên máy chủ web hay một định dạng khác trên thiết bị hoặc web, hãy định dạng các đề xuất dưới dạng hàng trong bảng và trình bày chúng bằng Cursor
.
Hệ thống hiểu được một số cột, nhưng chỉ có 2 cột là bắt buộc:
_ID
- Mã nhận dạng hàng là số nguyên duy nhất cho mỗi đề xuất. Hệ thống yêu cầu điều này để trình bày các đề xuất trong một
ListView
. SUGGEST_COLUMN_TEXT_1
- Chuỗi xuất hiện dưới dạng đề xuất.
Tất cả các cột sau đây đều không bắt buộc. Hầu hết các vấn đề này sẽ được thảo luận thêm trong các phần sau.
SUGGEST_COLUMN_TEXT_2
- Một chuỗi. Nếu
Cursor
của bạn có cột này, thì tất cả các đề xuất sẽ được cung cấp ở định dạng hai dòng. Chuỗi trong cột này xuất hiện dưới dạng dòng văn bản thứ hai, nhỏ hơn bên dưới văn bản đề xuất chính. Giá trị này có thể là giá trị rỗng hoặc trống để cho biết không có văn bản phụ. SUGGEST_COLUMN_ICON_1
- Một tài nguyên có thể vẽ, nội dung hoặc chuỗi URI của tệp. Nếu
Cursor
của bạn có cột này, thì tất cả các đề xuất đều được cung cấp ở định dạng biểu tượng và văn bản, trong đó biểu tượng có thể vẽ ở bên trái. Giá trị này có thể là giá trị rỗng hoặc bằng 0 để cho biết không có biểu tượng trong hàng này. SUGGEST_COLUMN_ICON_2
- Một tài nguyên có thể vẽ, nội dung hoặc chuỗi URI của tệp. Nếu
Cursor
của bạn có cột này, thì tất cả các đề xuất đều được cung cấp ở định dạng biểu tượng và văn bản, trong đó biểu tượng nằm ở bên phải. Giá trị này có thể là null hoặc 0 để cho biết không có biểu tượng trong hàng này. SUGGEST_COLUMN_INTENT_ACTION
- Một chuỗi thao tác theo ý định. Nếu cột này tồn tại và chứa một giá trị tại hàng đã cho, thì thao tác được xác định ở đây sẽ được dùng khi tạo ý định của đề xuất. Nếu không có phần tử này, hành động sẽ được lấy từ trường
android:searchSuggestIntentAction
trong cấu hình có thể tìm kiếm của bạn. Nếu hành động của bạn giống nhau cho tất cả các đề xuất, thì việc chỉ định hành động bằng cách sử dụngandroid:searchSuggestIntentAction
và bỏ qua cột này sẽ hiệu quả hơn. SUGGEST_COLUMN_INTENT_DATA
- Một chuỗi URI dữ liệu. Nếu cột này tồn tại và chứa một giá trị tại hàng đã cho, thì dữ liệu này sẽ được dùng khi tạo ý định của đề xuất. Nếu bạn không cung cấp phần tử này, dữ liệu sẽ được lấy từ trường
android:searchSuggestIntentData
trong cấu hình có thể tìm kiếm của bạn. Nếu không có nguồn nào được cung cấp, thì trường dữ liệu của ý định sẽ là giá trị rỗng. Nếu dữ liệu của bạn giống nhau cho tất cả các đề xuất hoặc có thể được mô tả bằng một phần không đổi và một mã nhận dạng cụ thể, thì bạn nên chỉ định dữ liệu đó bằngandroid:searchSuggestIntentData
và bỏ qua cột này. SUGGEST_COLUMN_INTENT_DATA_ID
- Một chuỗi đường dẫn URI. Nếu cột này tồn tại và chứa một giá trị tại hàng đã cho, thì "/" và giá trị này sẽ được thêm vào trường dữ liệu trong ý định.
Chỉ sử dụng thuộc tính này nếu trường dữ liệu do thuộc tính
android:searchSuggestIntentData
chỉ định trong cấu hình có thể tìm kiếm đã được đặt thành một chuỗi cơ sở thích hợp. SUGGEST_COLUMN_INTENT_EXTRA_DATA
- Dữ liệu tuỳ ý. Nếu cột này tồn tại và chứa một giá trị tại một hàng nhất định, thì đây là dữ liệu bổ sung được dùng khi tạo ý định đề xuất.
Nếu không được cung cấp, trường dữ liệu bổ sung của ý định sẽ có giá trị rỗng. Cột này cho phép các đề xuất cung cấp dữ liệu bổ sung được đưa vào dưới dạng một phần bổ sung trong khoá
EXTRA_DATA_KEY
của ý định. SUGGEST_COLUMN_QUERY
- Nếu cột này tồn tại và phần tử này tồn tại ở hàng đã cho, thì đây là dữ liệu được dùng khi tạo truy vấn của đề xuất, được đưa vào dưới dạng một phần bổ sung trong khoá
QUERY
của ý định. Đây là thông số bắt buộc nếu hành động của đề xuất làACTION_SEARCH
, nhưng không bắt buộc trong trường hợp khác. SUGGEST_COLUMN_SHORTCUT_ID
- Chỉ dùng khi đưa ra đề xuất cho Hộp tìm kiếm nhanh. Cột này cho biết liệu một đề xuất tìm kiếm có phải được lưu trữ dưới dạng lối tắt hay không và liệu đề xuất đó có phải được xác thực hay không. Các lối tắt thường được tạo khi người dùng nhấn vào một đề xuất trong Hộp tìm kiếm nhanh. Nếu thiếu, kết quả sẽ được lưu trữ dưới dạng một lối tắt và không bao giờ được làm mới. Nếu bạn đặt thành
SUGGEST_NEVER_MAKE_SHORTCUT
, kết quả sẽ không được lưu trữ dưới dạng lối tắt. Nếu không, mã nhận dạng lối tắt sẽ được dùng để kiểm tra lại đề xuất mới nhất bằng cách sử dụngSUGGEST_URI_PATH_SHORTCUT
. SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING
- Chỉ dùng khi đưa ra đề xuất cho Hộp tìm kiếm nhanh. Cột này chỉ định rằng một biểu tượng xoay phải xuất hiện thay vì một biểu tượng trong
SUGGEST_COLUMN_ICON_2
trong khi lối tắt của đề xuất này đang làm mới trong Hộp tìm kiếm nhanh.
Hầu hết các cột này sẽ được thảo luận thêm trong các phần sau.
Khai báo ý định cho các đề xuất
Khi người dùng chọn một đề xuất trong danh sách xuất hiện bên dưới hộp thoại hoặc tiện ích tìm kiếm, hệ thống sẽ gửi một Intent
tuỳ chỉnh đến hoạt động có thể tìm kiếm của bạn. Bạn phải xác định hành động và dữ liệu cho ý định.
Khai báo thao tác theo ý định
Hành động phổ biến nhất cho một đề xuất tuỳ chỉnh là ACTION_VIEW
. Hành động này phù hợp khi bạn muốn mở một nội dung nào đó, chẳng hạn như định nghĩa của một từ, thông tin liên hệ của một người hoặc một trang web.
Tuy nhiên, thao tác theo ý định có thể là bất kỳ thao tác nào khác và có thể khác nhau đối với từng đề xuất.
Tuỳ thuộc vào việc bạn muốn tất cả các đề xuất sử dụng cùng một thao tác theo ý định hay không, bạn có thể xác định thao tác theo hai cách:
- Sử dụng thuộc tính
android:searchSuggestIntentAction
của tệp cấu hình có thể tìm kiếm để xác định thao tác cho tất cả các đề xuất, như trong ví dụ sau:<?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>
- Sử dụng cột
SUGGEST_COLUMN_INTENT_ACTION
để xác định hành động cho từng đề xuất. Để thực hiện việc này, hãy thêm cộtSUGGEST_COLUMN_INTENT_ACTION
vào bảng đề xuất và đối với mỗi đề xuất, hãy đặt hành động cần sử dụng vào cột đó, chẳng hạn như"android.intent.action.VIEW"
.
Bạn cũng có thể kết hợp hai kỹ thuật này. Ví dụ: bạn có thể thêm thuộc tính android:searchSuggestIntentAction
với một thao tác sẽ được dùng với tất cả các đề xuất theo mặc định, sau đó ghi đè thao tác này cho một số đề xuất bằng cách khai báo một thao tác khác trong cột SUGGEST_COLUMN_INTENT_ACTION
. Nếu bạn không thêm giá trị vào cột SUGGEST_COLUMN_INTENT_ACTION
, thì ý định mà bạn cung cấp trong thuộc tính android:searchSuggestIntentAction
sẽ được sử dụng.
Khai báo dữ liệu về ý định
Khi người dùng chọn một đề xuất, hoạt động có thể tìm kiếm của bạn sẽ nhận được ý định với thao tác mà bạn xác định (như đã thảo luận trong phần trước), nhưng ý định cũng phải mang theo dữ liệu để hoạt động của bạn xác định đề xuất nào được chọn. Cụ thể, dữ liệu phải là một giá trị riêng biệt cho từng đề xuất, chẳng hạn như mã nhận dạng hàng cho đề xuất trong bảng SQLite của bạn.
Khi nhận được ý định, bạn có thể truy xuất dữ liệu được đính kèm bằng getData()
hoặc getDataString()
.
Bạn có thể xác định dữ liệu đi kèm với ý định theo 2 cách:
- Xác định dữ liệu cho từng đề xuất trong cột
SUGGEST_COLUMN_INTENT_DATA
của bảng đề xuất.Cung cấp tất cả thông tin dữ liệu cần thiết cho từng ý định trong bảng đề xuất bằng cách thêm cột
SUGGEST_COLUMN_INTENT_DATA
rồi điền dữ liệu duy nhất cho từng hàng. Dữ liệu trong cột này được đính kèm vào ý định chính xác như bạn xác định trong cột này. Sau đó, bạn có thể truy xuất chuỗi này bằnggetData()
hoặcgetDataString()
. - Phân mảnh một URI dữ liệu thành hai phần: phần chung cho tất cả các đề xuất và phần riêng cho từng đề xuất. Đặt các phần này vào thuộc tính
android:searchSuggestintentData
của cấu hình có thể tìm kiếm và cộtSUGGEST_COLUMN_INTENT_DATA_ID
của bảng đề xuất, tương ứng.Ví dụ sau đây cho biết cách khai báo phần URI chung cho tất cả các đề xuất trong thuộc tính
android:searchSuggestIntentData
của cấu hình có thể tìm kiếm:<?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>
Thêm đường dẫn cuối cùng cho từng đề xuất (phần duy nhất) vào cột
SUGGEST_COLUMN_INTENT_DATA_ID
trong bảng đề xuất. Khi người dùng chọn một đề xuất, hệ thống sẽ lấy chuỗi từandroid:searchSuggestIntentData
, thêm dấu gạch chéo (/), rồi thêm giá trị tương ứng từ cộtSUGGEST_COLUMN_INTENT_DATA_ID
để tạo thành một URI nội dung hoàn chỉnh. Sau đó, bạn có thể truy xuấtUri
bằnggetData()
.
Thêm dữ liệu khác
Nếu cần thể hiện thêm thông tin về ý định của mình, bạn có thể thêm một cột bảng khác, chẳng hạn như SUGGEST_COLUMN_INTENT_EXTRA_DATA
. Cột này có thể lưu trữ thêm thông tin về đề xuất. Dữ liệu được lưu trong cột này sẽ được đặt trong EXTRA_DATA_KEY
của gói bổ sung của ý định.
Xử lý ý định
Sau khi cung cấp các đề xuất tìm kiếm tuỳ chỉnh bằng ý định tuỳ chỉnh, bạn cần có hoạt động có thể tìm kiếm để xử lý các ý định này khi người dùng chọn một đề xuất. Đây là ngoài việc xử lý ý định ACTION_SEARCH
mà hoạt động có thể tìm kiếm của bạn đã thực hiện. Dưới đây là ví dụ về cách bạn có thể xử lý các ý định trong lệnh gọi lại onCreate()
của hoạt động:
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); }
Trong ví dụ này, thao tác theo ý định là ACTION_VIEW
và dữ liệu mang một URI hoàn chỉnh trỏ đến mục được đề xuất, như được tổng hợp bởi chuỗi android:searchSuggestIntentData
và cột SUGGEST_COLUMN_INTENT_DATA_ID
. Sau đó, URI sẽ truyền đến phương thức showResult()
cục bộ. Phương thức này sẽ truy vấn nhà cung cấp nội dung cho mục do URI chỉ định.
Viết lại văn bản truy vấn
Theo mặc định, nếu người dùng di chuyển qua danh sách đề xuất bằng các nút điều khiển hướng, chẳng hạn như bằng bi xoay hoặc D-pad, thì văn bản truy vấn sẽ không cập nhật. Tuy nhiên, bạn có thể tạm thời viết lại văn bản truy vấn của người dùng khi văn bản đó xuất hiện trong hộp văn bản bằng một truy vấn khớp với đề xuất đang được lấy tiêu điểm. Điều này cho phép người dùng xem truy vấn được đề xuất, đồng thời họ có thể chọn hộp tìm kiếm và chỉnh sửa truy vấn trước khi gửi truy vấn đó dưới dạng một cụm từ tìm kiếm.
Bạn có thể viết lại văn bản truy vấn theo những cách sau:
- Thêm thuộc tính
android:searchMode
vào cấu hình có thể tìm kiếm của bạn bằng giá trị"queryRewriteFromText"
. Trong trường hợp này, nội dung trong cộtSUGGEST_COLUMN_TEXT_1
của đề xuất được dùng để viết lại văn bản truy vấn. - Thêm thuộc tính
android:searchMode
vào cấu hình có thể tìm kiếm của bạn bằng giá trị"queryRewriteFromData"
. Trong trường hợp này, nội dung trong cộtSUGGEST_COLUMN_INTENT_DATA
của đề xuất được dùng để viết lại văn bản truy vấn. Chỉ sử dụng phương thức này với các URI hoặc định dạng dữ liệu khác mà người dùng có thể thấy, chẳng hạn như URL HTTP. Đừng sử dụng các lược đồ URI nội bộ để viết lại truy vấn theo cách này. - Cung cấp một chuỗi văn bản truy vấn duy nhất trong cột
SUGGEST_COLUMN_QUERY
của bảng đề xuất. Nếu cột này xuất hiện và chứa một giá trị cho đề xuất hiện tại, thì giá trị đó sẽ được dùng để viết lại văn bản truy vấn và ghi đè một trong hai cách triển khai trước đó.
Hiển thị các cụm từ tìm kiếm được đề xuất cho Hộp tìm kiếm nhanh
Sau khi bạn định cấu hình ứng dụng để cung cấp các đề xuất tìm kiếm tuỳ chỉnh, việc cung cấp các đề xuất đó cho Hộp tìm kiếm nhanh có thể truy cập trên toàn cầu cũng dễ dàng như việc sửa đổi cấu hình có thể tìm kiếm để thêm android:includeInGlobalSearch
với giá trị "true"
.
Trường hợp duy nhất cần thêm công việc là khi nhà cung cấp nội dung của bạn yêu cầu quyền đọc. Trong trường hợp đó, bạn cần thêm một phần tử <path-permission>
để trình cung cấp cấp cho Hộp tìm kiếm nhanh quyền đọc đối với trình cung cấp nội dung của bạn, như minh hoạ trong ví dụ sau:
<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>
Trong ví dụ này, nhà cung cấp hạn chế quyền đọc và ghi đối với nội dung.
Phần tử <path-permission>
sửa đổi quy định hạn chế bằng cách cấp quyền đọc cho nội dung bên trong tiền tố đường dẫn "/search_suggest_query"
khi có quyền "android.permission.GLOBAL_SEARCH"
. Thao tác này cấp quyền truy cập vào Hộp tìm kiếm nhanh để hộp này có thể truy vấn nhà cung cấp nội dung của bạn để đưa ra đề xuất.
Nếu trình cung cấp nội dung của bạn không thực thi quyền đọc, thì Hộp tìm kiếm nhanh sẽ đọc quyền này theo mặc định.
Bật tính năng đề xuất trên thiết bị
Theo mặc định, các ứng dụng không được phép cung cấp đề xuất trong Hộp tìm kiếm nhanh, ngay cả khi chúng được định cấu hình để làm như vậy. Người dùng chọn có đưa đề xuất từ ứng dụng của bạn vào Hộp tìm kiếm nhanh hay không bằng cách mở Mục có thể tìm kiếm (nằm trong Cài đặt > Tìm kiếm) và bật ứng dụng của bạn làm mục có thể tìm kiếm.
Mỗi ứng dụng có trong Hộp tìm kiếm nhanh đều có một mục trong trang cài đặt Mục có thể tìm kiếm. Mục này bao gồm tên của ứng dụng và một đoạn mô tả ngắn về nội dung có thể tìm kiếm trong ứng dụng và được cung cấp để đề xuất trong Hộp tìm kiếm nhanh. Để xác định văn bản mô tả cho ứng dụng có thể tìm kiếm, hãy thêm thuộc tính android:searchSettingsDescription
vào cấu hình có thể tìm kiếm, như trong ví dụ sau:
<?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>
Hãy tạo chuỗi cho android:searchSettingsDescription
ngắn gọn nhất có thể và nêu rõ nội dung có thể tìm kiếm. Ví dụ: "Nghệ sĩ, đĩa nhạc và bài hát" đối với ứng dụng nhạc hoặc "Ghi chú đã lưu" đối với ứng dụng ghi chú. Việc cung cấp nội dung mô tả này là rất quan trọng để người dùng biết loại đề xuất được cung cấp. Luôn thêm thuộc tính này khi android:includeInGlobalSearch
là true.
Vì người dùng phải truy cập vào trình đơn cài đặt để bật tính năng đề xuất tìm kiếm cho ứng dụng của bạn, nên nếu tìm kiếm là một khía cạnh quan trọng của ứng dụng, hãy cân nhắc cách truyền đạt điều đó cho người dùng. Ví dụ: bạn có thể cung cấp một ghi chú trong lần đầu tiên người dùng khởi chạy ứng dụng để giải thích cách bật đề xuất tìm kiếm cho Hộp tìm kiếm nhanh.
Quản lý các lối tắt đề xuất của Hộp tìm kiếm nhanh
Những đề xuất mà người dùng chọn trong Hộp tìm kiếm nhanh có thể tự động trở thành lối tắt. Đây là những đề xuất mà hệ thống sao chép từ trình cung cấp nội dung của bạn để có thể nhanh chóng truy cập vào đề xuất mà không cần phải truy vấn lại trình cung cấp nội dung.
Theo mặc định, chế độ này được bật cho tất cả các đề xuất mà Hộp tìm kiếm nhanh truy xuất. Tuy nhiên, nếu dữ liệu đề xuất của bạn thay đổi theo thời gian, thì bạn có thể yêu cầu làm mới các lối tắt. Ví dụ: nếu các đề xuất của bạn đề cập đến dữ liệu động, chẳng hạn như trạng thái hiện diện của một người liên hệ, thì hãy yêu cầu làm mới các lối tắt đề xuất khi hiển thị cho người dùng. Để thực hiện việc này, hãy thêm SUGGEST_COLUMN_SHORTCUT_ID
vào bảng đề xuất. Bạn có thể dùng cột này để định cấu hình hành vi của lối tắt cho từng đề xuất theo một trong những cách sau:
Khiến Hộp tìm kiếm nhanh truy vấn lại trình cung cấp nội dung của bạn để lấy phiên bản mới của lối tắt đề xuất.
Cung cấp một giá trị trong cột
SUGGEST_COLUMN_SHORTCUT_ID
để truy vấn lại đề xuất cho phiên bản mới mỗi khi lối tắt xuất hiện. Lối tắt này nhanh chóng hiển thị bất kỳ dữ liệu nào có sẵn gần đây nhất cho đến khi truy vấn làm mới trả về. Tại thời điểm đó, đề xuất sẽ được làm mới bằng thông tin mới. Truy vấn làm mới được gửi đến trình cung cấp nội dung của bạn bằng đường dẫn URI làSUGGEST_URI_PATH_SHORTCUT
thay vìSUGGEST_URI_PATH_QUERY
.Hãy đảm bảo
Cursor
mà bạn trả về chứa một đề xuất bằng cách sử dụng cùng các cột như đề xuất ban đầu hoặc để trống, cho biết rằng lối tắt không còn hợp lệ. Trong trường hợp đó, đề xuất sẽ biến mất và lối tắt sẽ bị xoá.Nếu một đề xuất đề cập đến dữ liệu có thể mất nhiều thời gian hơn để làm mới, chẳng hạn như một lần làm mới dựa trên mạng, bạn cũng có thể thêm cột
SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING
vào bảng đề xuất với giá trị true để hiện một biểu tượng xoay tiến trình cho biểu tượng bên phải cho đến khi quá trình làm mới hoàn tất. Mọi giá trị không phải là true đều không hiển thị chỉ báo tiến trình.Ngăn nội dung đề xuất bị sao chép vào một lối tắt.
Cung cấp giá trị
SUGGEST_NEVER_MAKE_SHORTCUT
trong cộtSUGGEST_COLUMN_SHORTCUT_ID
. Trong trường hợp này, đề xuất sẽ không bao giờ được sao chép vào một lối tắt. Bạn chỉ cần làm việc này nếu hoàn toàn không muốn đề xuất đã sao chép trước đó xuất hiện. Nếu bạn cung cấp một giá trị bình thường cho cột, thì lối tắt đề xuất chỉ xuất hiện cho đến khi truy vấn làm mới trả về.Cho phép áp dụng hành vi mặc định của lối tắt.
Để trống
SUGGEST_COLUMN_SHORTCUT_ID
cho mỗi đề xuất không thay đổi và có thể lưu dưới dạng lối tắt.
Nếu không có đề xuất nào thay đổi, thì bạn không cần cột SUGGEST_COLUMN_SHORTCUT_ID
.
Giới thiệu về thứ hạng đề xuất của Hộp tìm kiếm nhanh
Sau khi bạn cung cấp các đề xuất tìm kiếm của ứng dụng cho Hộp tìm kiếm nhanh, thứ hạng của Hộp tìm kiếm nhanh sẽ xác định cách các đề xuất được hiển thị cho người dùng đối với một cụm từ tìm kiếm cụ thể. Điều này có thể phụ thuộc vào số lượng ứng dụng khác có kết quả cho truy vấn đó và tần suất người dùng chọn kết quả của bạn so với kết quả của các ứng dụng khác. Không có gì đảm bảo về cách các đề xuất của bạn được xếp hạng hoặc liệu các đề xuất của ứng dụng có xuất hiện hay không cho một cụm từ tìm kiếm nhất định. Nhìn chung, việc cung cấp kết quả chất lượng sẽ làm tăng khả năng các đề xuất của ứng dụng xuất hiện ở vị trí nổi bật. Còn những ứng dụng cung cấp đề xuất chất lượng thấp có nhiều khả năng bị xếp hạng thấp hơn hoặc không hiển thị.