Search code examples
androidsqliteuriandroid-contentprovider

Android - Content Provider - Choose SQL into query method


My android app has a content provider called MensagemProvider. I want to be able to run query1 or query2 for LIST URI into query method. How implement this and how to call from CursorLoader ? Thanks a lot!

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;

    }

}

In my fragment

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

Solution

  • It's probably easier to use a different URI for different queries. If that makes the most sense for your situation, I would choose that first.

    However, if you want to use the same URI, you could append a query parameter to the URI that is interpreted as a boolean value and determines whether to use the other query. Something like:

    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;
    }
    

    Then you build your URI like this:

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