我正在尝试在我的应用中制作自定义搜索建议。我从文档和Searchable字典示例开始。但是,这个例子对我来说并不是那么好,所以我开始进行一些测试以确切地知道如何制作它,因为互联网上也没有太多的教程。
通常我的应用程序现在有2个数据库 - 一个正常,第二个列数较少 - FTS3。我想要实现的是将建议提供者连接到此FTS3表。
我试图做的是,现在使用简单的功能,在搜索框中键入任何字母后返回建议整个数据库(大约200条记录)。我知道限制50条记录,但我不认为这是问题所在。
这是来自Provider代码的片段。我发现,当您输入文字时,提供者会转到选项SEARCH_SUGGEST
:
// UriMatcher stuff
private static final int SEARCH_WORDS = 0;
private static final int GET_WORD = 1;
private static final int SEARCH_SUGGEST = 2;
private static final int REFRESH_SHORTCUT = 3;
private static final UriMatcher mUriMatcher = buildUriMatcher();
/**
* Builds up a UriMatcher for search suggestion and shortcut refresh queries.
*/
private static UriMatcher buildUriMatcher() {
Log.d(TAG,"urimatcher");
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
// to get definitions...
matcher.addURI(AUTHORITY, "mydb", SEARCH_WORDS);
matcher.addURI(AUTHORITY, "mydb/#", GET_WORD);
// to get suggestions...
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
return matcher;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
switch (mUriMatcher.match(uri)) {
case SEARCH_SUGGEST:
Log.d(TAG,"SEARCH_SUGGEST");
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return getSuggestions(selectionArgs[0]);
case SEARCH_WORDS:
Log.d(TAG,"SEARCH_WORDS");
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return search(selectionArgs[0]);
case GET_WORD:
Log.d(TAG,"GET_WORD");
return null;
default:
Log.d(TAG,"default");
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
private Cursor getSuggestions(String query) {
String[] columns = { MyDBAdapter.KEY_TITLE,MyDBAdapter.KEY_ID};
Log.d(TAG,"query1: " + query);
try{
Cursor tmp = MyDB.getAllEntriesFTS(false, columns,
null, null, null, null, MyDBAdapter.KEY_TITLE, null, query);
Log.d(TAG,"cursor: " + Integer.toString(tmp.getCount()));
}
catch(Exception e)
{
Log.d(TAG,e.toString());
}
return tmp;
}
在getSuggestions
中,我放置了通常应该有效的代码,但事实并非如此。仅在此处使用时不起作用。当我在其他活动中使用它来获取listview的光标时一切都很好。这里它返回我的NullPointerException。
所以越来越深入我在getAllEntriesFTS
方法中添加了一些Log标记,这个方法看起来像这样:
public Cursor getAllEntriesFTS(boolean distinct, String[] result_columns,
String selection, String[] selectionArgs, String groupBy,
String having, String orderBy, String limit, String query) {
Log.d(TAG,"query db: " + query);
String[] columns = { MyDBAdapter.KEY_TITLE, MyDBAdapter.KEY_ID};
Log.d(TAG,"columns: " + Integer.toString(result_columns.length));
Cursor allRows = null;
try{
allRows = db.query(distinct, DATABASE_TABLE_FTS, columns,
null, null, null, null, MyDBAdapter.KEY_TITLE, null);
Log.d(TAG,"OK");
}
catch(Exception e)
{
Log.d(TAG, e.toString());//it always goes there with NullPointerExceptionwhen used in provider
}
Log.d(TAG,Integer.toString(allRows.getCount()));
return allRows;
}
所以,generalny说它应该将游标返回到整个数据库,而是抛出它不应该是NullPointerException。
有人可以告诉我,我做错了什么以及应该怎么做?
答案 0 :(得分:0)
感谢JB Nizet我能找到我的错误。我以为我研究过Google的好榜样,但我错了。
问题是在游标调用之前缺少数据库打开。它应该是这样的:
private Cursor getSuggestions(String query) {
String[] columns = { MyDBAdapter.KEY_TITLE,MyDBAdapter.KEY_ID};
Log.d(TAG,"query1: " + query);
try{
MyDB.open();
Cursor tmp = MyDB.getAllEntriesFTS(false, columns,
null, null, null, null, MyDBAdapter.KEY_TITLE, null, query);
MyDB.close();
Log.d(TAG,"cursor: " + Integer.toString(tmp.getCount()));
}
catch(Exception e)
{
Log.d(TAG,e.toString());
}
return tmp;
}
谢谢大家告诉我。