【发布时间】:2014-08-11 23:14:14
【问题描述】:
很抱歉,还有另一个 UriMatcher 线程,但我无法理解为什么它不起作用。
我的 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;
}
这是我的合同类:
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);
}
}
}
在 UriMatcher 的代码片段中,您可以看到由各自函数生成的每种 Uri 的示例。实际的 AGENDA 和 AGENDA_ID Uris 匹配没有任何问题。但是,我无法让其他三个中的任何一个工作。 AGENDA_AFTER和AGENDA_BEFORE总是得到-1和AGENDA_DATE_FILTERED总是匹配到AGENDA。
我在 Udacity 课程中的 Sunshine Android 应用程序上做了很多工作,其中他们有以下 Uris 之一,我的一个基于该 Uris:
content://com.example.android.sunshine.app/weather/94043?date=20140809
content://com.example.app /agenda /after?date=2014-08-09%2014%3A17%3A51
如下匹配:
matcher.addURI(authority, WeatherContract.PATH_WEATHER + "/*/*", WEATHER_WITH_LOCATION_AND_DATE);
matcher.addURI(authority, AppsssContract.PATH_AGENDA + "/*/*", AGENDA_AFTER);
阳光一匹配没有任何问题,但我的根本没有。即使我更改了顺序并将其放在顶部,以防止任何其他 Uri 匹配(从 here 获得的信息),它仍然不起作用。
让我们以这个为例:
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);
根据this 发布的每个段的 Uri 匹配器匹配。所以首先它应该匹配AppContract.PATH_AGENDA,即agenda。后面跟着一个/ 来分隔路径。在这之后我们得到AppContract.AgendaEntry.AGENDA_AFTER,它就是after。这也应该匹配。最后但同样重要的是,我们有一个/*,它应该与问号和日期查询匹配。但不知何故它无法匹配,我真的想知道我到底错过了什么。
我也想不通为什么这个匹配器应该匹配 Uri:
matcher.addURI(authority, AppContract.PATH_AGENDA, AGENDA);
content://com.example.app/agenda?limit=before&date=2014-08-09%2014%3A35%3A47
似乎? 似乎没有被正确地视为一个片段,尽管在上面的阳光示例中它似乎确实将其识别为一个片段。这是我能想到为什么它匹配这个 Uri 而不是 AGENDA_BEFORE 和 AGENDA_AFTER 的 Uris 的唯一原因
我遇到了一堆类似的问题,例如this(由于我使用的变量不应该成为问题)或this(变量中没有/)或this导致我到this 问题,我仍然发现它的信息量最大。但我似乎仍然无法弄清楚。虽然我猜它会变得非常简单。
【问题讨论】:
标签: android uri android-contentprovider