Android SearchRecentSuggestionsProvider 查询限制

Android SearchRecentSuggestionsProvider query limit

我正在使用搜索建议框架,这就是这种情况。我得到一些查询字符串并从内容解析器进行查询,但问题是我无法限制结果。找到了几个解决方案,但它们对我不起作用。

我的内容提供者正在扩展 SearchRecentSuggestionsProvider 并在清单中声明,这里是查询 uri Uri URI = Uri.parse("content://" + AUTHORITY + "/search_suggest_query");

溶胶 1: 向 uri 添加查询参数

SearchSuggestionProvider.URI.buildUpon().appendQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT, String.valueOf(5)).build()

溶胶 2: 在 sortOrder 查询参数中添加限制

getContentResolver().query(URI, null, "?", new String[]{searchQuery}, "_id asc limit 5");

在这两种情况下,查询 returns 搜索建议中的所有行。有谁知道如何限制这样的查询?

下面是基础class框架中SearchRecentSuggestionsProvider中的查询方法

/**
     * This method is provided for use by the ContentResolver.  Do not override, or directly
     * call from your own code.
     */
    // TODO: Confirm no injection attacks here, or rewrite.
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 
            String sortOrder) {

您可能可以覆盖它并实施限制 - 但正如您所见,上面的评论明确指出 "do not override"。 在现有方法中没有强制执行限制。

但是我在 stack-overflow 和其他网站上的一些其他答案中看到人们确实覆盖了它。

示例: Use SearchRecentSuggestionsProvider with some predefined terms?

基于此,我认为您可以尝试一下 - 重写查询方法并添加您自己的支持限制结果的实现。解析您在查询方法中使用的SearchManager.SUGGEST_PARAMETER_LIMIT,并使用它来限制返回的结果。

其实我们找错地方了。 经过一番调查,终于找到窍门了。

在结果屏幕上(我们将查询保存到搜索 SearchRecentSuggestions 的地方)我们调用此方法

SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
                    SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE);
suggestions.saveRecentQuery(query, null);

SearchRecentSuggestions 负责将此查询保存到内容提供商。

此 class 有一个名为 truncateHistory() 的受保护方法以及此文档

Reduces the length of the history table, to prevent it from growing too large.

所以解决方案很简单,创建一个自定义 class,覆盖此方法,并调用具有所需限制的超级实现。

示例如下

public class SearchRecentSuggestionsLimited extends SearchRecentSuggestions {

    private int limit;

    public SearchRecentSuggestionsLimited(Context context, String authority, int mode, int limit) {
        super(context, authority, mode);
        this.limit = limit;
    }

    @Override
    protected void truncateHistory(ContentResolver cr, int maxEntries) {
        super.truncateHistory(cr, limit);
    }
}