我想使用自定义提供程序提出搜索建议我遵循Google示例,可搜索的字典但我得到了一个例外。 这是我的代码:
public class MyCustomSuggestionProvider extends ContentProvider {
// UriMatcher stuff
private static final int SEARCH_CATEGORY = 0;
private static final int GET_CATEGORY = 1;
private static final int SEARCH_SUGGEST = 2;
private static final int REFRESH_SHORTCUT = 3;
private static final UriMatcher sURIMatcher = buildUriMatcher();
private MyDB myDB;
String TAG = "MyCustomSuggestionProvider";
public static String AUTHORITY = "com.pooya.autosender.database.MyCustomSuggestionProvider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"+Constants.DATABASE_NAME);
@Override
public boolean onCreate() {
myDB = new MyDB(getContext());
return false;
}
private static UriMatcher buildUriMatcher() {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
// to get definitions...
matcher.addURI(AUTHORITY, Constants.DATABASE_NAME, SEARCH_CATEGORY);
matcher.addURI(AUTHORITY, Constants.DATABASE_NAME+"/#", GET_CATEGORY);
// to get suggestions...
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
/* The following are unused in this implementation, but if we include
* {@link SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} as a column in our suggestions table, we
* could expect to receive refresh queries when a shortcutted suggestion is displayed in
* Quick Search Box, in which case, the following Uris would be provided and we
* would return a cursor with a single item representing the refreshed suggestion data.
*/
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT, REFRESH_SHORTCUT);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/*", REFRESH_SHORTCUT);
return matcher;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
// Use the UriMatcher to see what kind of query we have and format the db query accordingly
switch (sURIMatcher.match(uri)) {
case SEARCH_SUGGEST:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return getSuggestions(selectionArgs[0]);
case SEARCH_CATEGORY:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return search(selectionArgs[0]);
case GET_CATEGORY:
return getWord(uri);
case REFRESH_SHORTCUT:
return refreshShortcut(uri);
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
private Cursor getSuggestions(String query) {
query = query.toLowerCase();
String[] columns = new String[] {
BaseColumns._ID,
Constants.CATEGORY_NAME,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
return myDB.getCategoryMatches(query, columns);
}
private Cursor search(String query) {
query = query.toLowerCase();
String[] columns = new String[] {
BaseColumns._ID,
Constants.CATEGORY_NAME};
return myDB.getCategoryMatches(query, columns);
}
private Cursor getWord(Uri uri) {
String rowId = uri.getLastPathSegment();
String[] columns = new String[] {
Constants.CATEGORY_NAME};
return myDB.getCategory(rowId, columns);
}
private Cursor refreshShortcut(Uri uri) {
/* This won't be called with the current implementation, but if we include
* {@link SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} as a column in our suggestions table, we
* could expect to receive refresh queries when a shortcutted suggestion is displayed in
* Quick Search Box. In which case, this method will query the table for the specific
* word, using the given item Uri and provide all the columns originally provided with the
* suggestion query.
*/
String rowId = uri.getLastPathSegment();
String[] columns = new String[] {
BaseColumns._ID,
Constants.CATEGORY_NAME,
SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
return myDB.getCategory(rowId, columns);
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
return null;
}
@Override
public int delete(Uri uri, String s, String[] strings) {
return 0;
}
@Override
public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
return 0;
}
}
我在清单中的提供者是:
<provider android:name=".database.MyCustomSuggestionProvider" android:authorities="com.pooya.autosender.database.MyCustomSuggestionProvider" />
我的表是:
private static final String CREATE_CATEGOTY_TABLE="CREATE VIRTUAL TABLE "+
Constants.CATEGORY_TABLE_NAME+" USING fts4("+
Constants.CATEGORY_NAME+");";
这是我的logcat:
10-07 08:24:53.909 1159-1159/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.pooya.autosender, PID: 1159
java.lang.ExceptionInInitializerError
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.ActivityThread.installProvider(ActivityThread.java:4778)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4385)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4325)
at android.app.ActivityThread.access$1500(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.content.UriMatcher.addURI(UriMatcher.java:195)
at com.pooya.autosender.database.MyCustomSuggestionProvider.buildUriMatcher(MyCustomSuggestionProvider.java:34)
at com.pooya.autosender.database.MyCustomSuggestionProvider.<clinit>(MyCustomSuggestionProvider.java:20)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.ActivityThread.installProvider(ActivityThread.java:4778)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4385)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4325)
at android.app.ActivityThread.access$1500(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
10-07 08:25:02.039 389-403/? E/WindowManager﹕ Starting window AppWindowToken{b210f808 token=Token{b21521d0 ActivityRecord{b223a7c8 u0 com.pooya.autosender/.activity.MainActivity t4}}} timed out