Android - Content Provider - 选择 SQL 进入查询方式

Android - Content Provider - Choose SQL into query method

我的 android 应用程序有一个名为 MensagemProvider 的内容提供程序。我希望能够将 运行 query1 或 query2 for LIST URI 转化为查询方法。如何实现这个以及如何从 CursorLoader 调用?非常感谢!

public class MensagemProvider extends ContentProvider {

    private DBManager db;

    public static final String DATABASE_TABLE = "MENSAGEM";

    // Content Provider Uri and Authority
    public static final String AUTHORITY = "br.com.soma.provider.MensagemProvider";
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/mensagem");

    // MIME types used for listing amantes or looking up a single amante
    private static final String MENSAGENS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.br.com.soma.mensagens";
    private static final String MENSAGEM_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.br.com.soma.mensagem";

    // UriMatcher stuff
    private static final int LIST_MENSAGEM = 0;
    private static final int ITEM_MENSAGEM = 1;
    private static final UriMatcher URI_MATCHER = buildUriMatcher();

    private static UriMatcher buildUriMatcher() {
        UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        matcher.addURI(AUTHORITY, "mensagem", LIST_MENSAGEM);
        matcher.addURI(AUTHORITY, "mensagem/#", ITEM_MENSAGEM);
        return matcher;
    }

    @Override
    public String getType(Uri uri) {
        switch (URI_MATCHER.match(uri)) {
            case LIST_MENSAGEM:
                return MENSAGENS_MIME_TYPE;
            case ITEM_MENSAGEM:
                return MENSAGEM_MIME_TYPE;
            default:
                throw new IllegalArgumentException("Unknown Uri: " + uri);
        }
    }


    @Override
    public Cursor query(Uri uri, String[] ignored1, String selection, String[] selectionArgs, String sortOrder) {

        Cursor c;
        switch (URI_MATCHER.match(uri)) {
            case LIST_MENSAGEM:
                c = db.getReadableDatabase().query(DATABASE_TABLE, projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case ITEM_MENSAGEM:
                c = db.getReadableDatabase().query(DATABASE_TABLE, projection, COLUMN_MENSAGEMID + "=?", new String[]{Long.toString(ContentUris.parseId(uri))}, null, null, null, null);
                if (c.getCount() > 0) {
                    c.moveToFirst();
                }
                break;
            default:
                throw new IllegalArgumentException("Unknown Uri: " + uri);
        }
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;

    }

}

在我的片段中

@Override
public Loader<Cursor> onCreateLoader(int ignored, Bundle args) {
    return new CursorLoader(getActivity(), MensagemProvider.CONTENT_URI, null, null, null, null);
}

针对不同的查询使用不同的 URI 可能更容易。如果这对您的情况最有意义,我会首先选择它。

但是,如果您想使用相同的 URI,您可以将查询参数附加到 URI,该参数被解释为布尔值并确定是否使用其他查询。类似于:

public static final String PARAM_USE_ALTERNATE_QUERY = "use_alt_query";
...
private boolean getBooleanQueryParameter(Uri uri, String paramName) {
    String paramValue = uri.getQueryParameter(paramName);
    return TextUtils.equals(paramValue, "true") || TextUtils.equals(paramValue, "1");
}
...
switch(URI_MATCHER.match(uri)) {
    case LIST_MENSAGEM:
        boolean useAltQuery = getBooleanQueryParameter(PARAM_USE_ALTERNATE_QUERY);
        if (useAltQuery) {
            db.query(...); // Query #1
        } else {
            db.query(...); // Query #1
        }
        break;
}

然后像这样构建 URI:

MensagemProvider.CONTENT_URI.buildUpon()
    .appendQueryParameter(MensagemProvider.PARAM_USE_ALTERNATE_QUERY, "true")
    .build();