views:

323

answers:

1

I've built my own content provider and I've run into an instance where I need to execute a query and include a limit param.

The method call to managedQuery doesn't include this param and there fore I see no way to implement this w/o somehow overriding the managedQuery method?

I've created a second query method in my content provider which accepts an additional param, the limit param but I don't think I can make the managedQuery method call this custom query method of my content provider.

What's the best way to do this?

For reference, here is my content provider class... package com.isi.sa;

import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.isi.sa.SATest.Questions;
import com.isi.sa.SATest.Scores;

public class SAContentProvider extends ContentProvider {
  private static final String TAG            = "SAProvider";
    private static final String DATABASE_NAME      = "sa.db";
    private static final int DATABASE_VERSION      = 1;
    private static final String QUESTIONS_TABLE_NAME  = "questions";
    private static final String SCORES_TABLE_NAME    = "scores";

    private static HashMap<String, String> sQuestionsProjectionMap;
    private static HashMap<String, String> sScoresProjectionMap;

    private static final int QUESTIONS = 1;
    private static final int QUESTION_ID = 2;
    private static final int SCORES = 3;
    private static final int SCORE_ID = 4;

    private DatabaseHelper mOpenHelper;
    private static final UriMatcher sUriMatcher;


  @Override
  public boolean onCreate() {
        mOpenHelper = new DatabaseHelper(getContext());
    return true;
  }


  @Override
  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

    switch (sUriMatcher.match(uri)){
    case QUESTIONS:
      qb.setTables(QUESTIONS_TABLE_NAME);
      qb.setProjectionMap(sQuestionsProjectionMap);
      if (TextUtils.isEmpty(sortOrder)) sortOrder = Questions.DEFAULT_SORT_ORDER;
      break;

    case QUESTION_ID:
      qb.setTables(QUESTIONS_TABLE_NAME);
      qb.setProjectionMap(sQuestionsProjectionMap);
      qb.appendWhere(Questions._ID + "=" + uri.getPathSegments().get(1));
      if (TextUtils.isEmpty(sortOrder)) sortOrder = Questions.DEFAULT_SORT_ORDER;
      break;

    case SCORES:
      qb.setTables(SCORES_TABLE_NAME);
      qb.setProjectionMap(sScoresProjectionMap);
      if (TextUtils.isEmpty(sortOrder)) sortOrder = Scores.DEFAULT_SORT_ORDER;
      break;

    case SCORE_ID:
      qb.setTables(SCORES_TABLE_NAME);
      qb.setProjectionMap(sScoresProjectionMap);
      qb.appendWhere(Scores._ID + "=" + uri.getPathSegments().get(1));
      if (TextUtils.isEmpty(sortOrder)) sortOrder = Scores.DEFAULT_SORT_ORDER;
      break;

    default:
      throw new IllegalArgumentException("Unknown URI " + uri);
    }

        // Get the database and run the query
    SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);

        // Tell the cursor what uri to watch, so it knows when its source data changes
    c.setNotificationUri(getContext().getContentResolver(), uri);
    return c;
  }


  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, String limit) {
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

    switch (sUriMatcher.match(uri)){
    case QUESTIONS:
      qb.setTables(QUESTIONS_TABLE_NAME);
      qb.setProjectionMap(sQuestionsProjectionMap);
      if (TextUtils.isEmpty(sortOrder)) sortOrder = Questions.DEFAULT_SORT_ORDER;
      break;

    case QUESTION_ID:
      qb.setTables(QUESTIONS_TABLE_NAME);
      qb.setProjectionMap(sQuestionsProjectionMap);
      qb.appendWhere(Questions._ID + "=" + uri.getPathSegments().get(1));
      if (TextUtils.isEmpty(sortOrder)) sortOrder = Questions.DEFAULT_SORT_ORDER;
      break;

    case SCORES:
      qb.setTables(SCORES_TABLE_NAME);
      qb.setProjectionMap(sScoresProjectionMap);
      if (TextUtils.isEmpty(sortOrder)) sortOrder = Scores.DEFAULT_SORT_ORDER;
      break;

    case SCORE_ID:
      qb.setTables(SCORES_TABLE_NAME);
      qb.setProjectionMap(sScoresProjectionMap);
      qb.appendWhere(Scores._ID + "=" + uri.getPathSegments().get(1));
      if (TextUtils.isEmpty(sortOrder)) sortOrder = Scores.DEFAULT_SORT_ORDER;
      break;

    default:
      throw new IllegalArgumentException("Unknown URI " + uri);
    }

        // Get the database and run the query
    SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder, limit);

        // Tell the cursor what uri to watch, so it knows when its source data changes
    c.setNotificationUri(getContext().getContentResolver(), uri);
    return c;
  }


  @Override
  public Uri insert(Uri uri, ContentValues initialValues) {
        ContentValues values;
        SQLiteDatabase db;
        long rowId;

        if (sUriMatcher.match(uri) != QUESTIONS && sUriMatcher.match(uri) != SCORES) {
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        if (initialValues != null){
          values = new ContentValues(initialValues);
        }
        else{
          values = new ContentValues();
        }

    switch (sUriMatcher.match(uri)){
    case QUESTIONS:
          if (values.containsKey(Questions.QUESTION) == false) values.put(Questions.QUESTION, "");
        if (values.containsKey(Questions.QUESTION) == false) values.put(Questions.ANSWER, -1);
        if (values.containsKey(Questions.OPTION1) == false) values.put(Questions.OPTION1, "");
        if (values.containsKey(Questions.OPTION2) == false) values.put(Questions.OPTION2, "");
        if (values.containsKey(Questions.OPTION3) == false) values.put(Questions.OPTION3, "");
        if (values.containsKey(Questions.OPTION4) == false) values.put(Questions.OPTION4, "");
        if (values.containsKey(Questions.OPTION5) == false) values.put(Questions.OPTION5, "");
        if (values.containsKey(Questions.OPTION6) == false) values.put(Questions.OPTION6, "");
        if (values.containsKey(Questions.OPTION7) == false) values.put(Questions.OPTION7, "");
        if (values.containsKey(Questions.OPTION8) == false) values.put(Questions.OPTION8, "");
        if (values.containsKey(Questions.OPTION9) == false) values.put(Questions.OPTION9, "");
        if (values.containsKey(Questions.OPTION10) == false) values.put(Questions.OPTION10, "");

          if (values.get(Questions.QUESTION).toString().length() > 0 &&
            values.get(Questions.ANSWER).toString() != "-1" &&
            values.get(Questions.OPTION1).toString().length() > 0){
            db = mOpenHelper.getWritableDatabase();
            rowId = db.insert(QUESTIONS_TABLE_NAME, Questions.QUESTION, values);
            if (rowId > 0) {
                Uri noteUri = ContentUris.withAppendedId(Questions.CONTENT_URI, rowId);
                getContext().getContentResolver().notifyChange(noteUri, null);
                return noteUri;
            }
          }
          break;

    case SCORES:
        if (values.containsKey(Scores.SCORE) == false) values.put(Scores.SCORE, -1);
        if (values.containsKey(Scores.DATE_CREATED) == false) values.put(Scores.DATE_CREATED, DateFormat.getDateTimeInstance().format(new Date()));

          if (values.get(Scores.SCORE).toString() != "-1"){
            db = mOpenHelper.getWritableDatabase();
            rowId = db.insert(SCORES_TABLE_NAME, Scores.SCORE, values);
            if (rowId > 0) {
                Uri noteUri = ContentUris.withAppendedId(Questions.CONTENT_URI, rowId);
                getContext().getContentResolver().notifyChange(noteUri, null);
                return noteUri;
            }
      }
      break;
    }    

        throw new SQLException("Failed to insert row into " + uri);
  }


  @Override
  public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    int count;

    switch(sUriMatcher.match(uri)){
    case QUESTIONS:
            count = db.update(QUESTIONS_TABLE_NAME, values, where, whereArgs);
            break;

    case QUESTION_ID:
            String questionId = uri.getPathSegments().get(1);
            count = db.update(QUESTIONS_TABLE_NAME, values, Questions._ID + "=" + questionId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
      break;

    case SCORES:
            count = db.update(SCORES_TABLE_NAME, values, where, whereArgs);
      break;

    case SCORE_ID:
            String scoreId = uri.getPathSegments().get(1);
            count = db.update(SCORES_TABLE_NAME, values, Scores._ID + "=" + scoreId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
      break;

    default:
      throw new IllegalArgumentException("Unknown URI " + uri);
    }

        getContext().getContentResolver().notifyChange(uri, null);
    return count;
  }


  @Override
  public int delete(Uri uri, String where, String[] whereArgs) {
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    int count;

    switch(sUriMatcher.match(uri)){
    case QUESTIONS:
            count = db.delete(QUESTIONS_TABLE_NAME, where, whereArgs);
            break;

    case QUESTION_ID:
            String questionId = uri.getPathSegments().get(1);
            count = db.delete(QUESTIONS_TABLE_NAME, Questions._ID + "=" + questionId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
      break;

    case SCORES:
            count = db.delete(SCORES_TABLE_NAME, where, whereArgs);
      break;

    case SCORE_ID:
            String scoreId = uri.getPathSegments().get(1);
            count = db.delete(SCORES_TABLE_NAME, Scores._ID + "=" + scoreId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
      break;

    default:
      throw new IllegalArgumentException("Unknown URI " + uri);
    }

        getContext().getContentResolver().notifyChange(uri, null);
    return count;
  }


  @Override
  public String getType(Uri uri) {
        switch (sUriMatcher.match(uri)) {
        case QUESTIONS:
            return Questions.CONTENT_TYPE;
        case QUESTION_ID:
            return Questions.CONTENT_ITEM_TYPE;
        case SCORES:
            return Scores.CONTENT_TYPE;
        case SCORE_ID:
            return Scores.CONTENT_ITEM_TYPE;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }
  }


    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
          db.execSQL("CREATE TABLE questions ("
              + "_id INTEGER PRIMARY KEY AUTOINCREMENT,"
              + "question TEXT,"
              + "answer INTEGER,"
              + "option1 TEXT,"
              + "option2 TEXT,"
              + "option3 TEXT,"
              + "option4 TEXT,"
              + "option5 TEXT,"
              + "option6 TEXT,"
              + "option7 TEXT,"
              + "option8 TEXT,"
              + "option9 TEXT,"
              + "option10 TEXT);");

            db.execSQL("CREATE TABLE scores ("
                + "_id INTEGER PRIMARY KEY AUTOINCREMENT,"
                + "score NUMERIC,"
                + "date_created TEXT);");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
        }        
    }


    static {
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sUriMatcher.addURI(SATest.AUTHORITY, "questions", QUESTIONS);
        sUriMatcher.addURI(SATest.AUTHORITY, "questions/#", QUESTION_ID);
        sUriMatcher.addURI(SATest.AUTHORITY, "scores", SCORES);
        sUriMatcher.addURI(SATest.AUTHORITY, "scores/#", SCORE_ID);

        sQuestionsProjectionMap = new HashMap<String, String>();
        sQuestionsProjectionMap.put(Questions._ID, Questions._ID);
        sQuestionsProjectionMap.put(Questions.QUESTION, Questions.QUESTION);
        sQuestionsProjectionMap.put(Questions.ANSWER, Questions.ANSWER);
        sQuestionsProjectionMap.put(Questions.OPTION1, Questions.OPTION1);
        sQuestionsProjectionMap.put(Questions.OPTION2, Questions.OPTION2);
        sQuestionsProjectionMap.put(Questions.OPTION3, Questions.OPTION3);
        sQuestionsProjectionMap.put(Questions.OPTION4, Questions.OPTION4);
        sQuestionsProjectionMap.put(Questions.OPTION5, Questions.OPTION5);
        sQuestionsProjectionMap.put(Questions.OPTION6, Questions.OPTION6);
        sQuestionsProjectionMap.put(Questions.OPTION7, Questions.OPTION7);
        sQuestionsProjectionMap.put(Questions.OPTION8, Questions.OPTION8);
        sQuestionsProjectionMap.put(Questions.OPTION9, Questions.OPTION9);
        sQuestionsProjectionMap.put(Questions.OPTION10, Questions.OPTION10);

        sScoresProjectionMap = new HashMap<String, String>();
        sScoresProjectionMap.put(Scores._ID, Scores._ID);
        sScoresProjectionMap.put(Scores.SCORE, Scores.SCORE);
        sScoresProjectionMap.put(Scores.DATE_CREATED, Scores.DATE_CREATED);
    }
}
+2  A: 

If your consumer of the content provider is in the same application as the content provider itself, don't use the content provider -- go straight to the database. ContentProvider is designed for inter-process communication, so it adds overhead and limits your API.

CommonsWare
@CommonsWare: Thanks. I am using it for the same application. I'll look into just using a SQLiteOpenHelper then.
Ryan