Minh Tuan NGUYEN Minh Tuan NGUYEN - 1 month ago 16
Android Question

Get wrong context in android

I'm quite new to Android developing and I'm currently building a note-taking app with text note and checklist function. However, there is a bug that I'm currently confuse with. It happens when user try to add new item to the checklist and the app just route the method to an unwanted one.

I don't know what's wrong with my code, might be something with the context. Therefore I will put my source code here and hopefully someone might figure it out. Thanks for your support

Here is the relevent code after user clicking add item:

NoteEditorActivity

ChecklistManager.newInstance(NoteEditorActivity.this).create(item);


ChecklistManager

public long create(CheckItem item) {
ContentValues values = new ContentValues();
values.put(Constants.CL_COL_ID, item.getId());
//put some data
Uri result = clContext.getContentResolver().insert(ChecklistContentProvider.CONTENT_URI, values); //BUG: insert command points to notecontentprovider's one
long id = Long.parseLong(result.getLastPathSegment());
return id;
}


and it route to the insert method in NoteContentProvider instead of the one in ChecklistContentProvider

public Uri insert(Uri uri, ContentValues values) {
int type = URI_MATCHER.match(uri);
SQLiteDatabase db = dbHelper.getWritableDatabase();
Long id;
switch (type){
case NOTES:
id = db.insert(Constants.NOTES_TABLE, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI at notecontent: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH_NOTE + "/" + id);
}


Here is the bug

java.lang.IllegalArgumentException: Unknown URI at notecontent: content://cmc.note.data.provider/checklist
at cmc.note.data.NoteContentProvider.insert(NoteContentProvider.java:88)
at android.content.ContentProvider$Transport.insert(ContentProvider.java)
at android.content.ContentResolver.insert(ContentResolver.java)
at cmc.note.data.ChecklistManager.create(ChecklistManager.java:43)
at cmc.note.activities.NoteEditorActivity$1.onClick(NoteEditorActivity.java:107)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:157)
at android.os.Handler.dispatchMessage(Handler.java)
at android.os.Looper.loop(Looper.java)
at android.app.ActivityThread.main(ActivityThread.java)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:163)

Answer

The immediate problem is that you have NoteContentProvider registered for the authority you're querying on. The UriMatcher there doesn't have a match for the checklist path, so it's throwing that IllegalArgumentException.

Generally speaking, apps only need one Provider, which determines the result data from the path and ID on the URI. You can easily combine the two Provider classes you currently have into one, and merge their UriMatcher setups and CRUD methods. When a request is received, simply determine which table you need to access from the URI using the matcher, and perform the necessary database operation accordingly.

Comments