I'm sorry that there's yet another UriMatcher thread, but I simply can't wrap my head around why it isn't working.
I've got the following code for my UriMatcher:
private static final int AGENDA = 200;
private static final int AGENDA_ID = 201;
private static final int AGENDA_AFTER = 202;
private static final int AGENDA_BEFORE = 203;
private static final int AGENDA_DATE_FILTERED = 204;
public static UriMatcher buildUriMatcher() {
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
final String authority = AppContract.CONTENT_AUTHORITY;
// Checks for a collection of items:
// Ex: content://com.example.app/agenda
matcher.addURI(authority, AppContract.PATH_AGENDA, AGENDA);
// Checks for a single item
// Ex: content://com.example.app/agenda/1
matcher.addURI(authority, AppContract.PATH_AGENDA + "/#", AGENDA_ID);
// Checks for a collection of items
// Ex: content://com.example.app/agenda/after?date=2014-08-09%2014%3A17%3A51
matcher.addURI(authority, AppContract.PATH_AGENDA + "/" + AppContract.AgendaEntry.AGENDA_AFTER + "/*", AGENDA_AFTER);
// Checks for a collection of items
// Ex: content://com.example.app/agenda/before?date=2014-08-09%2014%3A17%3A51
matcher.addURI(authority, AppContract.PATH_AGENDA + "/" + AppContract.AgendaEntry.AGENDA_BEFORE + "/*", AGENDA_BEFORE);
// Check for a collection of items
// Ex: content://com.example.app/agenda?limit=before&date=2014-08-09%2014%3A35%3A47
matcher.addURI(authority, AppContract.PATH_AGENDA + "/*/*", AGENDA_DATE_FILTERED);
return matcher;
}
And this is my Contract class:
public class AppContract {
public static final String CONTENT_AUTHORITY = "com.example.app";
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final String PATH_AGENDA = "agenda";
/* Inner class that defines the table contents of the location table */
public static final class AgendaEntry implements BaseColumns {
public static final Uri CONTENT_URI =
BASE_CONTENT_URI.buildUpon().appendPath(PATH_AGENDA).build();
public static final String CONTENT_TYPE =
"vnd.android.cursor.dir/" + CONTENT_AUTHORITY + "/" + PATH_AGENDA;
public static final String CONTENT_ITEM_TYPE =
"vnd.android.cursor.item/" + CONTENT_AUTHORITY + "/" + PATH_AGENDA;
// Used in the Uri to select events
public static final String AGENDA_BEFORE = "before";
public static final String AGENDA_AFTER = "after";
public static final String LIMIT = "limit";
// Table name
public static final String TABLE_NAME = "agenda";
// Table columns
public static final String COLUMN_APP_ID = "app_id";
public static final String COLUMN_DATE = "date";
public static final String COLUMN_TITLE = "title";
public static final String COLUMN_SMALL_IMAGE_URL = "small_image_url";
public static final String COLUMN_LARGE_IMAGE_URL = "large_image_url";
public static final String COLUMN_HEADLINE = "headline";
public static final String COLUMN_MESSAGE = "message";
public static final String COLUMN_LAST_UPDATE = "last_update";
public static Uri buildAgendaUri(long id) {
return ContentUris.withAppendedId(CONTENT_URI, id);
}
public static Uri buildAgendaWithStartDate(String startDate) {
return CONTENT_URI.buildUpon().appendPath(AGENDA_AFTER).appendQueryParameter(COLUMN_DATE, startDate).build();
}
public static Uri buildAgendaWithEndDate(String endDate) {
return CONTENT_URI.buildUpon().appendPath(AGENDA_BEFORE).appendQueryParameter(COLUMN_DATE, endDate).build();
}
public static Uri buildAgendaWithDateLimit(String limit, String date) {
return CONTENT_URI.buildUpon().appendQueryParameter(LIMIT, limit).appendQueryParameter(COLUMN_DATE, date).build();
}
public static String getLimitFromUri(Uri uri) {
return uri.getQueryParameter(LIMIT);
}
public static String getDateFromUri(Uri uri) {
return uri.getQueryParameter(COLUMN_DATE);
}
}
}
In the code piece for the UriMatcher you can see examples for each kind of Uri generated by their respective functions. Actual AGENDA
and AGENDA_ID
Uris are matched without any issues. However I can't get any of the other three to work. AGENDA_AFTER
and AGENDA_BEFORE
always get -1
and AGENDA_DATE_FILTERED
is always matched to AGENDA
.
I've based a lot of this on the Sunshine Android app from the Udacity course, in which they have one of the following Uris on which I based one of mine:
content://com.example.android.sunshine.app/weather/94043?date=20140809
content://com.example.app /agenda /after?date=2014-08-09%2014%3A17%3A51
Which are matched like this:
matcher.addURI(authority, WeatherContract.PATH_WEATHER + "/*/*", WEATHER_WITH_LOCATION_AND_DATE);
matcher.addURI(authority, AppsssContract.PATH_AGENDA + "/*/*", AGENDA_AFTER);
The sunshine one matches without any issues, however mine simply doesn't. Even when I change the order and put it on top, to prevent any other Uri from matching (info gotten from here), it still doesn't work.
So lets take this one as an example:
content://com.example.app/agenda/after?date=2014-08-09%2014%3A17%3A51
matcher.addURI(authority, AppContract.PATH_AGENDA + "/" + AppContract.AgendaEntry.AGENDA_AFTER + "/*", AGENDA_AFTER);
According to this post the Uri matcher matches per segment. So first it should match AppContract.PATH_AGENDA
which is simply agenda
. This is followed by a /
to seperate the path. After this we get AppContract.AgendaEntry.AGENDA_AFTER
which is simply after
. This should also match. Last but not least we have a /*
which should match to the question mark and the date query. But somehow it can't match and I'm really wondering what exactly I'm missing.
I also can't figure out why this matcher should match the Uri:
matcher.addURI(authority, AppContract.PATH_AGENDA, AGENDA);
content://com.example.app/agenda?limit=before&date=2014-08-09%2014%3A35%3A47
It seems as if the ?
isn't correctly seen as a segment, even though in the Sunshine example above it does seem to recognize it as one. That's the only reason I can think of why it does match this Uri and not the Uris for AGENDA_BEFORE
and AGENDA_AFTER
I went through a bunch of similar questions, for example this (shouldn't be an issue due to the variables I use) or this (no /
in the variables) or this which lead me to this question which I still found the most informative. But I still can't seem to figure it out. Though I guess it'll turn out to be something very simple.