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

Bạn có thể đưa ra nội dung đề xuất tìm kiếm dựa trên các cụm từ tìm kiếm gần đây trong hộp thoại tìm kiếm hoặc tiện ích tìm kiếm trên Android. Ví dụ: nếu người dùng truy vấn "chó con", thì cụm từ tìm kiếm đó sẽ xuất hiện dưới dạng một đề xuất khi họ nhập lại cụm từ tìm kiếm đó. Hình 1 cho thấy ví dụ về hộp thoại tìm kiếm với các đề xuất truy vấn gần đây.

Trước khi bắt đầu, hãy triển khai hộp thoại tìm kiếm hoặc tiện ích tìm kiếm cho các nội dung tìm kiếm cơ bản trong ứng dụng. Để tìm hiểu cách thực hiện, hãy xem bài viết Tạo giao diện tìm kiếm.

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ó các đề xuất truy vấn gần đây.

Các cụm từ tìm kiếm đề xuất gần đây là nội dung tìm kiếm đã lưu. 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 ACTION_SEARCH với đề xuất đó là cụm từ tìm kiếm mà hoạt động tìm kiếm của bạn đã xử lý.

Để cung cấp đề xuất về cụm từ tìm kiếm gần đây, bạn cần:

  • Triển khai một hoạt động có thể tìm kiếm.
  • Tạo một trình cung cấp nội dung mở rộng SearchRecentSuggestionsProvider và khai báo mã này trong tệp kê khai ứng dụng của bạn.
  • 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ụm từ tìm kiếm được đề xuất.
  • Lưu truy vấn vào trình cung cấp nội dung của bạn mỗi khi thực thi một nội dung tìm kiếm.

Giống như việc hiển thị hộp thoại tìm kiếm, hệ thống Android cũng hiển thị các đề xuất tìm kiếm bên dưới hộp thoại hoặc tiện ích tìm kiếm. Bạn cung cấp nguồn để hệ thống truy xuất nội dung đề xuất.

Khi hệ thống xác định rằng hoạt động của bạn có thể tìm kiếm được và cung cấp đề xuất tìm kiếm, những điều sau đây sẽ xảy ra khi người dùng nhập một cụm từ tìm kiếm:

  1. Hệ thống sẽ lấy văn bản cụm từ tìm kiếm – bất cứ nội dung nào người dùng bắt đầu nhập – rồi gửi một truy vấn đến trình cung cấp nội dung chứa 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 khớp với 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.

Khi các đề xuất truy vấn gần đây được hiển thị, những điều sau có thể xảy ra:

  • Nếu người dùng nhập một khoá 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ẽ được lặp lại và danh sách đề xuất sẽ được cập nhật.
  • 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, ý định ACTION_SEARCH 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 văn bản đề xuất làm truy vấn.

Lớp SearchRecentSuggestionsProvider mà bạn mở rộng cho trình cung cấp nội dung sẽ tự động thực hiện công việc trong các bước trước đó, vì vậy, bạn sẽ không cần viết mã nhiều.

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

Trình cung cấp nội dung bạn cần cho các đề xuất truy vấn gần đây là một cách triển khai của SearchRecentSuggestionsProvider. Lớp học này sẽ làm mọi việc cho bạn. Bạn chỉ cần viết một hàm khởi tạo lớp thực thi một dòng mã.

Ví dụ: dưới đây là cách triển khai đầy đủ của một trình cung cấp nội dung cho các đề xuất truy vấn gần đây:

Kotlin

class MySuggestionProvider : SearchRecentSuggestionsProvider() {
    init {
        setupSuggestions(AUTHORITY, MODE)
    }

    companion object {
        const val AUTHORITY = "com.example.MySuggestionProvider"
        const val MODE: Int = SearchRecentSuggestionsProvider.DATABASE_MODE_QUERIES
    }
}

Java

public class MySuggestionProvider extends SearchRecentSuggestionsProvider {
    public final static String AUTHORITY = "com.example.MySuggestionProvider";
    public final static int MODE = DATABASE_MODE_QUERIES;

    public MySuggestionProvider() {
        setupSuggestions(AUTHORITY, MODE);
    }
}

Lệnh gọi đến setupSuggestions() truyền tên của đơn vị quản lý tìm kiếm và chế độ cơ sở dữ liệu. Cơ quan quản lý tìm kiếm có thể là chuỗi duy nhất bất kỳ, nhưng tốt nhất là bạn nên sử dụng tên đủ điều kiện cho trình cung cấp nội dung của mình, chẳng hạn như tên gói theo sau là tên lớp của nhà cung cấp. Ví dụ: "com.example.MySuggestionProvider".

Chế độ cơ sở dữ liệu phải bao gồm DATABASE_MODE_QUERIES và có thể bao gồm DATABASE_MODE_2LINES (không bắt buộc). Chế độ này sẽ thêm một cột vào bảng đề xuất để bạn có thể cung cấp dòng văn bản thứ hai cho mỗi đề xuất. Nếu bạn muốn cung cấp hai dòng trong mỗi đề xuất, hãy xem ví dụ sau:

Kotlin

const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES

Java

public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

Khai báo trình cung cấp nội dung trong tệp kê khai ứng dụng với cùng một chuỗi uỷ quyền dùng trong lớp SearchRecentSuggestionsProvider và trong cấu hình có thể tìm kiếm. Ví dụ:

<application>
    <provider android:name=".MySuggestionProvider"
              android:authorities="com.example.MySuggestionProvider" />
    ...
</application>

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

Để định cấu hình hệ thống sử dụng trình cung cấp đề xuất, hãy thêm thuộc tính android:searchSuggestAuthorityandroid:searchSuggestSelection vào phần tử <searchable> trong tệp cấu hình có thể tìm kiếm. Ví dụ:

<?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.MySuggestionProvider"
    android:searchSuggestSelection=" ?" >
</searchable>

Giá trị của android:searchSuggestAuthority phải là tên đủ điều kiện cho trình cung cấp nội dung của bạn và khớp chính xác với thẩm quyền được sử dụng trong trình cung cấp nội dung, chẳng hạn như "com.example.MySuggestionProvider" trong các ví dụ trước.

Giá trị của android:searchSuggestSelection phải là một dấu chấm hỏi đứng sau một dấu cách: " ?". Đây là phần giữ chỗ cho đối số lựa chọn SQLite và được tự động thay thế bằng văn bản truy vấn do người dùng nhập.

Lưu truy vấn

Để điền sẵn bộ sưu tập các truy vấn gần đây, hãy thêm từng truy vấn mà hoạt động có thể tìm kiếm nhận được vào SearchRecentSuggestionsProvider. Để thực hiện việc này, hãy tạo một bản sao của SearchRecentSuggestions và gọi saveRecentQuery() mỗi khi hoạt động có thể tìm kiếm của bạn nhận được một truy vấn. Ví dụ: dưới đây là cách bạn có thể lưu truy vấn trong phương thức onCreate() của hoạt động:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    if (Intent.ACTION_SEARCH == intent.action) {
        intent.getStringExtra(SearchManager.QUERY)?.also { query ->
            SearchRecentSuggestions(this, MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE)
                    .saveRecentQuery(query, null)
        }
    }
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Intent intent  = getIntent();

    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
                MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);
        suggestions.saveRecentQuery(query, null);
    }
}

Hàm khởi tạo SearchRecentSuggestionsProvider yêu cầu cùng một quyền và chế độ cơ sở dữ liệu do trình cung cấp nội dung của bạn khai báo.

Phương thức saveRecentQuery() lấy chuỗi truy vấn tìm kiếm làm tham số đầu tiên và chuỗi thứ hai (không bắt buộc) được đưa vào làm dòng thứ hai của đề xuất hoặc giá trị rỗng. Tham số thứ hai chỉ được dùng nếu bạn bật chế độ hai dòng cho các đề xuất tìm kiếm bằng DATABASE_MODE_2LINES. Nếu bạn bật chế độ hai dòng, thì văn bản truy vấn sẽ khớp với dòng thứ hai khi hệ thống tìm các đề xuất phù hợp.

Xoá dữ liệu đề xuất

Để bảo vệ quyền riêng tư của người dùng, hãy luôn cung cấp cho người dùng một cách để xoá các đề xuất truy vấn gần đây. Để xoá nhật ký truy vấn, hãy gọi clearHistory(). Ví dụ:

Kotlin

SearchRecentSuggestions(this, HelloSuggestionsProvider.AUTHORITY, HelloSuggestionsProvider.MODE)
        .clearHistory()

Java

SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
        HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE);
suggestions.clearHistory();

Thực hiện việc này từ mục trình đơn, mục tuỳ chọn hoặc nút "Xoá nhật ký tìm kiếm" mà bạn chọn. Cung cấp hộp thoại xác nhận để xác minh rằng người dùng muốn xoá nhật ký tìm kiếm của họ.