Thêm cụm từ tìm kiếm được đề xuất tuỳ chỉnh

Khi sử dụng hộp thoại tìm kiếm hoặc tiện ích tìm kiếm trên 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 bạn. Ví dụ: nếu ứng dụng của bạn là từ điển, bạn có thể đề xuất từ trong từ điển khớp với văn bản đã nhập vào trường tìm kiếm trước khi người dùng nhập xong cụm từ tìm kiếm. Những đề xuất này rất hữu ích vì 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 cho thấy ví dụ về hộp thoại tìm kiếm với 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ể đưa các đề xuất đó vào Hộp tìm kiếm nhanh trên toàn hệ thống, cấp quyền truy cập vào nội dung từ bên ngoài ứng dụng của bạn.

Trước khi bạn thêm nội dung đề xuất tuỳ chỉnh, hãy triển khai hộp thoại tìm kiếm trên Android hoặc tiện ích tìm kiếm cho các nội dung tìm kiếm trong ứng dụng của bạn. Xem phần Tạo giao diện tìm kiếmNhà cung cấp nội dung.

Thông tin cơ bản

Hình 1. Ảnh chụp màn hình hộp thoại tìm kiếm có đề xuất tìm kiếm tuỳ chỉnh.

Khi người dùng chọn một đề xuất tuỳ chỉnh, hệ thống sẽ gửi 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 sẽ 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 theo ý định nào khác, đồng thời 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 trong từ điển để tìm kết quả trùng khớp.

Để cung cấp nội dung đề 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ó thể tìm kiếm cơ bản, 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ề trình cung cấp nội dung cung cấp các đề xuất tuỳ chỉnh.
  • Tạo 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 và khai báo trình cung cấp đó trong tệp kê khai.
  • Khai báo loại Intent sẽ 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.

Giống như hộp thoại tìm kiếm, hệ thống Android cũng cho thấy các đề xuất tìm kiếm. Bạn cần có một trình cung cấp nội dung để hệ thống có thể truy xuất các đề xuất của bạn. Hãy đọc bài viết về 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 được và đưa ra đề xuất tìm kiếm, quy trình sau đây sẽ diễn ra khi người dùng nhập một truy vấn:

  1. Hệ thống sẽ lấy văn bản cụm từ tìm kiếm (tức là mọi thông tin đã nhập cho đến thời điểm này) và thực hiện truy vấn đến trình cung cấp nội dung quản lý các nội dung đề xuất của bạn.
  2. Trình cung cấp nội dung của bạn sẽ 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.
  3. Hệ thống sẽ hiển thị danh sách các đề xuất do Cursor cung cấp.

Sau khi nội dung đề xuất tuỳ chỉnh xuất hiện, những điều sau có thể xảy ra:

  • Nếu người dùng nhập một chữ cái khác hoặc thay đổi truy vấn theo bất kỳ cách nào, thì các bước trước đó sẽ lặp lại và danh sách đề xuất sẽ cập nhật tương ứng.
  • Nếu người dùng thực hiện tìm kiếm, các đề xuất sẽ bị bỏ qua và nội dung tìm kiếm sẽ được gửi đến hoạt động có thể tìm kiếm của bạn bằng cách sử dụng ý định ACTION_SEARCH thông thường.
  • Nếu người dùng chọn một đề xuất, thì ý định sẽ được gửi đến hoạt động có thể tìm kiếm của bạn, kèm theo 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 đề xuất.

Sửa đổi cấu hình có thể tìm kiếm

Để hỗ trợ thêm 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 các thuộc tính bổ sung, tuỳ thuộc vào loại ý định mà bạn đính kèm vào mỗi đề xuất và cách bạn muốn định dạng 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 được đề cập trong các phần sau.

Tạo một trình cung cấp nội dung

Để tạo 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 trình cung cấp nội dung. Nhà cung cấp nội dung cho các đề xuất tuỳ chỉnh tương tự như bất kỳ nhà cung cấp nội dung nào khác. Tuy nhiên, đối với mỗi đề xuất bạn đưa ra, 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 trình cung cấp nội dung của bạn để cung cấp 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. Trong quá trình triển khai query(), trình cung cấp nội dung phải tìm kiếm dữ liệu đề xuất và trả về Cursor trỏ đến các hàng mà công cụ này 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 được thảo luận trong hai phần sau:

Xử lý truy vấn được đề xuất
Cách hệ thống gửi yêu cầu đến trì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 dự kiến trong Cursor được trả về cùng với mỗi truy vấn.

Xử lý truy vấn đề xuất

Khi yêu cầu các đề 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 đó. Hãy triển khai phương thức này để tìm kiếm dữ liệu đề xuất và trả về Cursor trỏ đến các đề xuất mà bạn cho là phù hợp.

Dưới đây là bản tóm tắt các tham số mà hệ thống chuyển đến phương thức query() của bạn, được liệt kê theo thứ tự:

  1. uri

    Luôn là 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 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/puppies
    

    Văn bản truy vấn ở cuối được mã hoá bằng 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 mộ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ính android:searchSuggestPath. Điều này chỉ cần thiết nếu bạn 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. Trong trường hợp này, hãy phân biệt nguồn của truy vấn đề xuất.

  2. projection
    Luôn rỗng.
  3. 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 có giá trị rỗng nếu bạn không khai báo thuộc tính android:searchSuggestSelection. Phần sau đây sẽ thảo luận thêm về vấn đề này.
  4. 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áo android:searchSuggestSelection, thì tham số này rỗng. Phần sau đây sẽ thảo luận kỹ hơn về vấn đề này.
  5. 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à đưa văn bản truy vấn vào làm đường dẫn cuối cùng của URI nội dung được chuyển vào tham số uri. Tuy nhiên, nếu bạn đưa một giá trị lựa chọn vào thuộc tính android:searchSuggestSelection của cấu hình có thể tìm kiếm, thì văn bản truy vấn sẽ chuyển dưới dạng phần tử đầu tiên của mảng chuỗi selectionArgs. Hai tuỳ chọn này được mô tả tiếp theo.

Nhận truy vấn trong URI

Theo mặc định, truy vấn này được thêm vào dưới dạng phân đoạn cuối cùng của tham số uri — đố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ư trong ví dụ sau:

Kotlin

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

Java

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

Thao tác này sẽ 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, thì phương thức query() của bạn có thể sẽ hợp lý hơn khi nhận mọi thứ cần thiết để thực hiện quá trình tra cứu, đồng thời bạn nên cho các tham số selectionselectionArgs mang 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 một dấu chấm hỏi (?) làm phần giữ chỗ cho cụm từ tìm kiếm thực tế. Hệ thống sẽ gọi query() với chuỗi lựa chọn làm tham số selection và cụm từ tìm kiếm là phần tử đầu tiên trong mảng selectionArgs.

Ví dụ: dưới đây là cách bạn có thể tạo thuộc tính android:searchSuggestSelection để tạo câu lệnh tìm kiếm dạng văn bản đầy đủ:

<?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 giá trị này đến phương thức query() của SQLite (dưới dạng đối số tương ứng), chúng sẽ được tổng hợp cùng nhau (nghĩa là dấu chấm hỏi sẽ được thay thế bằng văn bản truy vấn). Nếu bạn nhận được các truy vấn đề xuất theo cách này và cần thêm ký tự đại diện vào văn bản truy vấn, hãy thêm hoặc thêm tiền tố vào tham số selectionArgs, vì giá trị này được đặt trong dấu ngoặc kép và chèn vào vị trí dấu chấm hỏi.

Một thuộc tính khác trong ví dụ trước là android:searchSuggestIntentAction. Thuộc tính này xác định thao tác theo ý định được gửi cùng với từng ý định khi người dùng chọn một đề xuất. Vấn đề này sẽ được thảo luận kỹ hơn 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 bằng Cursor.

Hệ thống hiểu một số cột, nhưng chỉ bắt buộc phải có hai cột:

_ID
Mã hàng là số nguyên duy nhất cho mỗi đề xuất. Hệ thống yêu cầu thao tác này để trình bày đề xuất trong ListView.
SUGGEST_COLUMN_TEXT_1
Chuỗi được biểu thị ở dạng đề xuất.

Tất cả các cột sau đây là không bắt buộc. Hầu hết nội dung 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 bao gồm cột này, thì tất cả đề xuất sẽ được cung cấp ở định dạng hai dòng. Chuỗi trong cột này được hiển thị 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ể rỗng hoặc trống để biểu thị việc 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 tệp. Nếu Cursor bao gồm cột này, thì tất cả đề xuất sẽ được cung cấp ở định dạng biểu tượng dấu cộng văn bản với biểu tượng có thể vẽ ở bên trái. Giá trị này có thể rỗng hoặc 0 để thể hiện không có biểu tượng nào 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 tệp. Nếu Cursor bao gồm cột này, thì tất cả đề xuất sẽ được cung cấp ở định dạng biểu tượng dấu cộng văn bản với biểu tượng ở bên phải. Giá trị này có thể có giá trị rỗng hoặc 0 để thể hiện rằng không có biểu tượng nào 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ị ở hàng đã cho, thì thao tác được xác định ở đây sẽ được dùng khi hình thành ý định của đề xuất. Nếu phần tử này không được cung cấp, thì thao tác sẽ được thực hiện từ trường android:searchSuggestIntentAction trong cấu hình có thể tìm kiếm của bạn. Nếu thao tác của bạn là giống nhau đối với tất cả đề xuất, thì sẽ hiệu quả hơn nếu bạn chỉ định thao tác đó bằng cách sử dụng android:searchSuggestIntentAction và bỏ qua cột này.
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ị ở hàng đã cho, thì dữ liệu này sẽ được dùng khi hình thành ý định của đề xuất. Nếu phần tử không được cung cấp, 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 cung cấp nguồn nào, thì trường dữ liệu của ý định sẽ rỗng. Nếu dữ liệu của bạn giống nhau đối với tất 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ì sẽ hiệu quả hơn nếu bạn chỉ định dữ liệu đó bằng cách sử dụng android:searchSuggestIntentData và bỏ qua cột này.
SUGGEST_COLUMN_INTENT_DATA_ID
Một chuỗi đường dẫn của URI. Nếu cột này tồn tại và chứa một giá trị ở 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 kiểu 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ị ở một hàng nhất định, thì đây là dữ liệu bổ sung được dùng khi hình thành ý định của đề xuất. Nếu không được cung cấp, trường dữ liệu bổ sung của ý định sẽ rỗng. Cột này cho phép các đề xuất cung cấp thêm dữ liệu, được đưa vào dưới dạng khoá 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 nhất định, thì đây sẽ 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 bổ sung trong khoá QUERY của ý định. Bắt buộc phải có nếu hành động của đề xuất là ACTION_SEARCH, nhưng không bắt buộc.
SUGGEST_COLUMN_SHORTCUT_ID
Chỉ được dùng khi cung cấp nội dung đề xuất cho Hộp Tìm kiếm nhanh. Cột này cho biết liệu một cụm từ tìm kiếm có phải được lưu trữ dưới dạng lối tắt hay không và có phải được xác thực hay không. Lối tắt thường được tạo khi người dùng nhấn vào một nội dung đề xuất trong Hộp tìm kiếm nhanh. Nếu bị thiếu, kết quả sẽ được lưu trữ dưới dạng 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ã lối tắt sẽ được dùng để kiểm tra lại nhằm tìm đề xuất mới nhất bằng SUGGEST_URI_PATH_SHORTCUT.
SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING
Chỉ được dùng khi cung cấp nội dung đề xuất cho Hộp Tìm kiếm nhanh. Cột này chỉ định rằng một trình đơn vòng quay phải xuất hiện thay vì biểu tượng từ SUGGEST_COLUMN_ICON_2, trong khi lối tắt của đề xuất này đang được làm mới trong Hộp tìm kiếm nhanh.

Hầu hết những cột này sẽ được thảo luận thêm trong các phần sau.

Khai báo ý định cho đề xuất

Khi người dùng chọn một đề xuất trong danh sách xuất hiện trong 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 thao tác và dữ liệu cho ý định.

Khai báo thao tác theo ý định

Thao tác theo ý định phổ biến nhất cho đề xuất tuỳ chỉnh là ACTION_VIEW. Thao tác này phù hợp khi bạn muốn mở 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 người dùng hoặc trang web. Tuy nhiên, thao tác theo ý định có thể là bất kỳ hành động nào khác và có thể khác nhau tuỳ theo từng đề xuất.

Tuỳ thuộc vào việc bạn có muốn mọi đề 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 2 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ả đề 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ột SUGGEST_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 đó, 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ể đưa vào thuộc tính android:searchSuggestIntentAction với một thao tác sẽ được dùng với tất 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 đưa giá trị vào cột SUGGEST_COLUMN_INTENT_ACTION thì ý định cung cấp trong thuộc tính android:searchSuggestIntentAction sẽ được sử dụng.

Khai báo dữ liệu ý đị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 cùng 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 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à dữ liệu riêng biệt cho từng đề xuất, chẳng hạn như mã hàng cho đề xuất trong bảng SQLite. Khi nhận được ý định, bạn có thể truy xuất dữ liệu đính kèm bằng getData() hoặc getDataString().

Bạn có thể xác định dữ liệu đi kèm ý đị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 bao gồm cột SUGGEST_COLUMN_INTENT_DATA, sau đó điền dữ liệu duy nhất cho mỗi hàng vào cột đó. Dữ liệu từ cột này được đính kèm với ý định đúng như cách bạn xác định trong cột này. Sau đó, bạn có thể truy xuất dữ liệu này bằng getData() hoặc getDataString().

  • Phân mảnh URI dữ liệu thành hai phần: phần chung cho tất cả đề xuất và phần dành riêng cho mỗi đề xuất. Lần lượ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ột SUGGEST_COLUMN_INTENT_DATA_ID của bảng đề xuất.

    Ví dụ sau cho thấy cách khai báo phần URI chung cho mọi đề 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 riêng biệt) trong cột SUGGEST_COLUMN_INTENT_DATA_ID của 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 (/), sau đó thêm giá trị tương ứng từ cột SUGGEST_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ất Uri bằng getData().

Thêm dữ liệu khác

Nếu cần diễn đạt thêm thông tin bằng ý đị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ông tin bổ sung về đề xuất. Dữ liệu lưu trong cột này được đặt vào 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 đối tượng có ý định tuỳ chỉnh, bạn cần hoạt động có thể tìm kiếm của mình để xử lý các ý định này khi người dùng chọn một đề xuất. Chức năng này bổ sung cho 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 xử lý các ý định trong khi 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 đề xuất, được tổng hợp bằng chuỗi android:searchSuggestIntentData và cột SUGGEST_COLUMN_INTENT_DATA_ID. Sau đó, URI chuyển đến phương thức showResult() cục bộ để truy vấn trì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 thành phần đ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 với một truy vấn khớp với đề xuất được đặt tiêu điểm. Điều này cho phép người dùng xem cụm từ tìm kiếm đang được đề xuất và họ có thể chọn hộp tìm kiếm cũng như chỉnh sửa cụm từ tìm kiếm trước khi gửi đi dưới dạng một lượt tìm kiếm.

Bạn có thể viết lại văn bản truy vấn theo các cách sau:

  • Thêm thuộc tính android:searchMode vào cấu hình có thể tìm kiếm bằng giá trị "queryRewriteFromText". Trong trường hợp này, nội dung trong cột SUGGEST_COLUMN_TEXT_1 của đề xuất được dùng để ghi 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 bằng giá trị "queryRewriteFromData". Trong trường hợp này, nội dung trong cột SUGGEST_COLUMN_INTENT_DATA của đề xuất được dùng để ghi lại văn bản truy vấn. Chỉ dùng phương thức này với URI hoặc các định dạng dữ liệu khác nhằm mục đích hiển thị cho người dùng, chẳng hạn như các URL HTTP. Không dùng lược đồ URI nội bộ để ghi 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 có mặt và chứa giá trị cho đề xuất hiện tại, thì cột này sẽ được dùng để ghi lại văn bản truy vấn và ghi đè một trong những cách triển khai trước đó.

Hiển thị đề xuất tìm kiếm cho Hộp tìm kiếm nhanh

Khi bạn định cấu hình ứng dụng để cung cấp đề 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 của bạn để đưa android:includeInGlobalSearch với giá trị "true".

Trường hợp duy nhất cần thực hiện thêm tác vụ là khi trì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 phần tử <path-permission> để trình cung cấp cấp quyền đọc Hộp tìm kiếm nhanh cho trình cung cấp nội dung của mình, 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, ứng dụng cung cấp hạn chế quyền đọc và ghi 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 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 sẽ cấp quyền truy cập vào Hộp tìm kiếm nhanh để có thể truy vấn các đề xuất từ trình cung cấp nội dung của bạn.

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 đó 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 bật để cung cấp đề xuất trong Hộp tìm kiếm nhanh, ngay cả khi chúng được định cấu hình để thực hiện việc này. Người dùng chọn có đưa các đề 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ở Các mục có thể tìm kiếm (nằm trong phần 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 hiện có trên Hộp tìm kiếm nhanh đều có một mục nhập trong trang cài đặt Mục có thể tìm kiếm. Mục này bao gồm tên ứng dụng và nội dung mô tả ngắn về nội dung có thể tìm kiếm được trên ứng dụng cũng như nội dung được đề 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 của bạn, 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>

Tạo chuỗi cho android:searchSettingsDescription càng ngắn gọn càng tốt và nêu rõ nội dung có thể tìm kiếm được. Ví dụ: "Nghệ sĩ, đĩa nhạc và bản nhạc" đối với ứng dụng nhạc hoặc "Ghi chú đã lưu" đối với ứng dụng sổ tay. Việc cung cấp nội dung mô tả này là rất quan trọng để người dùng biết được loại đề xuất nào được cung cấp. Hãy luôn thêm thuộc tính này khi android:includeInGlobalSearch có giá trị 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, nên nếu tìm kiếm là một khía cạnh quan trọng trong ứng dụng của bạn, hãy xem xét cách truyền tải thông tin đó đến người dùng. Ví dụ: bạn có thể đưa ra ghi chú khi người dùng lần đầu chạy ứng dụng giải thích cách bật tính năng đề xuất tìm kiếm cho Hộp tìm kiếm nhanh.

Quản lý lối tắt đề xuất của Hộp Tìm kiếm nhanh

Các đề xuất mà người dùng chọn từ Hộp tìm kiếm nhanh có thể được tự động tạo thành lối tắt. Đây là các đề 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 đề xuất mà không cần truy vấn lại trình cung cấp nội dung của bạn.

Theo mặc định, tính năng này được bật cho mọi đề xuất do Hộp tìm kiếm nhanh truy xuất, nhưng 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 lối tắt. Ví dụ: nếu các đề xuất đề cập đến dữ liệu động, chẳng hạn như trạng thái hiện diện của một mục liên hệ, hãy yêu cầu làm mới các khẩu lệnh nhanh đề xuất khi hiển thị cho người dùng. Để thực hiện việc này, hãy đưa SUGGEST_COLUMN_SHORTCUT_ID vào bảng đề xuất. Bạn có thể sử dụng cột này để định cấu hình hành vi của khẩu lệnh nhanh cho mỗi đề xuất theo một trong các cách sau:

  • Giúp Hộp tìm kiếm nhanh truy vấn lại trình cung cấp nội dung của bạn để có 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 cho đề xuất cần được truy vấn lại để tạo phiên bản mới mỗi khi lối tắt xuất hiện. Khẩu lệnh nhanh sẽ nhanh chóng hiển thị cùng với 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ề. Lúc đó, đề 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.

    Đặt Cursor mà bạn trả về chứa một đề xuất sử dụng các cột giống như đề xuất ban đầu hoặc để trống. Điều này cho biết khẩu lệnh nhanh 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 làm mới hơn, chẳng hạn như làm mới dựa trên mạng, thì bạn cũng có thể thêm cột SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING vào bảng đề xuất có giá trị là true để hiển thị vòng quay 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. Bất kỳ giá trị nào không phải là giá trị true sẽ không cho thấy vòng quay tiến trình.

  • Ngăn việc sao chép đề xuất vào lối tắt.

    Cung cấp giá trị của SUGGEST_NEVER_MAKE_SHORTCUT trong cột SUGGEST_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. Điều này chỉ cần thiết nếu bạn 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 giá trị bình thường cho cột, thì lối tắt đề xuất sẽ chỉ xuất hiện cho đến khi truy vấn làm mới trả về.

  • Áp dụng hành vi mặc định của lối tắt.

    Hãy để trống SUGGEST_COLUMN_SHORTCUT_ID đối với mỗi đề xuất không thay đổi và có thể được 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ề xếp hạng đề xuất của Hộp tìm kiếm nhanh

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 Hộp tìm kiếm nhanh sẽ xác định cách các đề xuất hiển thị cho người dùng cho một truy vấn 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 cụm từ tìm kiếm đó 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 xếp hạng các đề xuất của bạn hoặc liệu các đề xuất của ứng dụng có hiển thị hoàn toàn cho một truy vấn nhất định hay không. Nhìn chung, việc cung cấp kết quả chất lượng cao sẽ làm tăng khả năng các đề xuất của ứng dụng được đưa ra ở vị trí nổi bật, đồng thời các ứng dụng đưa ra đề 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 được hiển thị.