问题
I have a Listview that should show all entries from database in my main activity. I'm using a Simple Cursor Adapter, but when I run as android application, it crashes. The application is stopped and finished. Something wrong is happenning.
Trace of the Crash
03-27 00:23:50.555: E/cm value(1589): false
03-27 00:23:59.643: E/AndroidRuntime(1589): FATAL EXCEPTION: main
03-27 00:23:59.643: E/AndroidRuntime(1589): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ec.idiomas/com.ec.idiomas.BancoDictionary}: java.lang.IllegalArgumentException: selectionArgs must be provided for the Uri: content://com.ec.idiomas.searchabledict.DictionaryProvider/dictionary
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.app.ActivityThread.access$600(ActivityThread.java:130)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.os.Handler.dispatchMessage(Handler.java:99)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.os.Looper.loop(Looper.java:137)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.app.ActivityThread.main(ActivityThread.java:4745)
03-27 00:23:59.643: E/AndroidRuntime(1589): at java.lang.reflect.Method.invokeNative(Native Method)
03-27 00:23:59.643: E/AndroidRuntime(1589): at java.lang.reflect.Method.invoke(Method.java:511)
03-27 00:23:59.643: E/AndroidRuntime(1589): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-27 00:23:59.643: E/AndroidRuntime(1589): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-27 00:23:59.643: E/AndroidRuntime(1589): at dalvik.system.NativeStart.main(Native Method)
03-27 00:23:59.643: E/AndroidRuntime(1589): Caused by: java.lang.IllegalArgumentException: selectionArgs must be provided for the Uri: content://com.ec.idiomas.searchabledict.DictionaryProvider/dictionary
03-27 00:23:59.643: E/AndroidRuntime(1589): at com.ec.idiomas.DictionaryProvider.query(DictionaryProvider.java:62)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.content.ContentProvider.query(ContentProvider.java:652)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.content.ContentProvider$Transport.query(ContentProvider.java:189)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.content.ContentResolver.query(ContentResolver.java:370)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.content.ContentResolver.query(ContentResolver.java:313)
03-27 00:23:59.643: E/AndroidRuntime(1589): at com.ec.idiomas.BancoDictionary.onCreate(BancoDictionary.java:107)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.app.Activity.performCreate(Activity.java:5008)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
03-27 00:23:59.643: E/AndroidRuntime(1589): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
03-27 00:23:59.643: E/AndroidRuntime(1589): ... 11 more
My Main Activity
public class BancoDictionary extends ListActivity {
public static final String PREFS_NAME = "MyPrefsFile1";
ListView mListView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mListView = (ListView) findViewById(R.id.list);
Cursor cursor = getContentResolver().query(DictionaryProvider.CONTENT_URI, new String[] {DictionaryDatabase.KEY_WORD, DictionaryDatabase.KEY_DEFINITION}, null, null, null);
startManagingCursor(cursor);
String[] columns = new String[] { DictionaryDatabase.KEY_WORD, DictionaryDatabase.KEY_DEFINITION };
int[] to = new int[] { R.id.word, R.id.definition };
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.list_item, cursor, columns, to);
mListView.setListAdapter(mAdapter);
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent wordIntent = new Intent(getApplicationContext(), WordActivity.class);
Uri data = Uri.withAppendedPath(DictionaryProvider.CONTENT_URI,
String.valueOf(id));
wordIntent.setData(data);
wordIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
wordIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(wordIntent);
}
});
}
}
DictionaryProvider
public class DictionaryProvider extends ContentProvider {
String TAG = "DictionaryProvider";
public static String AUTHORITY = "com.ec.idiomas.searchabledict.DictionaryProvider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/dictionary");
public static final String WORDS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +
"/vnd.ec.idiomas.searchabledict";
public static final String DEFINITION_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE +
"/vnd.eci.idiomas.searchabledict";
private DictionaryDatabase mDictionary;
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 sURIMatcher = buildUriMatcher();
private static UriMatcher buildUriMatcher() {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(AUTHORITY, "dictionary", SEARCH_WORDS);
matcher.addURI(AUTHORITY, "dictionary/#", GET_WORD);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT, REFRESH_SHORTCUT);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/*", REFRESH_SHORTCUT);
return matcher;
}
@Override
public boolean onCreate() {
mDictionary = new DictionaryDatabase(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
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_WORDS:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return search(selectionArgs[0]);
case GET_WORD:
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,
DictionaryDatabase.KEY_WORD,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
return mDictionary.getWordMatches(query, columns);
}
private Cursor search(String query) {
query = query.toLowerCase();
String[] columns = new String[] {
BaseColumns._ID,
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION};
return mDictionary.getWordMatches(query, columns);
}
private Cursor getWord(Uri uri) {
String rowId = uri.getLastPathSegment();
String[] columns = new String[] {
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION};
return mDictionary.getWord(rowId, columns);
}
private Cursor refreshShortcut(Uri uri) {
String rowId = uri.getLastPathSegment();
String[] columns = new String[] {
BaseColumns._ID,
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION,
SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
return mDictionary.getWord(rowId, columns);
}
@Override
public String getType(Uri uri) {
switch (sURIMatcher.match(uri)) {
case SEARCH_WORDS:
return WORDS_MIME_TYPE;
case GET_WORD:
return DEFINITION_MIME_TYPE;
case SEARCH_SUGGEST:
return SearchManager.SUGGEST_MIME_TYPE;
case REFRESH_SHORTCUT:
return SearchManager.SHORTCUT_MIME_TYPE;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
throw new UnsupportedOperationException();
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
}
}
回答1:
The log says it: Unable to start activity ComponentInfo{com.ec.idiomas/com.ec.idiomas.BancoDictionary}: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
回答2:
The error message says it all:
java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
See the documentation for ListActivity:
ListActivity has a default layout that consists of a single, full-screen list in the center of the screen. However, if you desire, you can customize the screen layout by setting your own view layout with setContentView() in onCreate(). To do this, your own view MUST contain a ListView object with the id "@android:id/list" (or list if it's in code)
You will have to change your ListView to conform to the requirements for ListActivity.
回答3:
It seems that the source of your problems is "Caused by: java.lang.IllegalArgumentException: selectionArgs must be provided
for the Uri: content://com.ec.idiomas.searchabledict.DictionaryProvider/dictionary".
You need to set selectionArgs
to solve your problem.
来源:https://stackoverflow.com/questions/36241964/simple-cursor-adapter-and-listview