UriMatcher无法正确匹配我的所有URI

时间:2014-08-11 23:14:15

标签: android uri android-contentprovider

对不起,还有另一个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的示例。实际AGENDAAGENDA_ID Uris匹配没有任何问题。但是,我不能让其他三个中的任何一个工作。 AGENDA_AFTERAGENDA_BEFORE始终获得-1AGENDA_DATE_FILTERED始终与AGENDA匹配。

我在Udacity课程的Sunshine Android应用程序中已经基于很多这样做了,其中他们有以下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而不是U AGENDA_BEFOREAGENDA_AFTER

的唯一原因

我经历了一系列类似的问题,例如this(由于我使用的变量不应该是一个问题)或this(没有/变量)或this引导我this问题,我仍然发现信息量最大的问题。但我似乎仍然无法弄明白。虽然我猜它会变得非常简单。

1 个答案:

答案 0 :(得分:0)

您需要将查询路径分隔为“/”。

不正确: content://com.example.app/agenda/after?date=2014-08-09%2014%3A17%3A51

更正 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);

正确: matcher.addURI(authority, AppContract.PATH_AGENDA + "/" + AppContract.AgendaEntry.AGENDA_AFTER, AGENDA_AFTER);

我希望它有所帮助。