Saturday, November 5, 2011

Simple Content Provider for db operations

At last I concluded, it is ContentProvider which we need to use for database operation ..
Content Providers  
Content providers store and retrieve data and make it accessible to all applications. They're the only way to share data across applications; 

  • Yes content providers are mainly aimed to share data amount different application
  • It can be also used inside our single application
  • There is no worries of closing and locking of db
  • It can be accessed from different activities,  services and Thread. Anywhere that have context object
  • I don't know is this a bad idea, I don't think so. Don't think it will reduce our data security. Our data can be accessed only with our AUTHORITY url
When a request is made via a ContentResolver the system inspects the authority of the given URI and passes the request to the content provider registered with the authority.
Now I'm trying to demonstrate the way how we can use ContentProvider in most simple way...
ContentProviderDb.java

public class ContentProviderDb extends ContentProvider{
 OurDatabaseHelper dbHelper ;
 public static final String AUTHORITY = "ourContentProviderAuthorities";//specific for our our app, will be specified in maninfed 
 public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
 
 @Override
 public boolean onCreate() {
  dbHelper = new OurDatabaseHelper(getContext());
  return true;
 }

 @Override
 public int delete(Uri uri, String where, String[] args) {
  String table = getTableName(uri);
     SQLiteDatabase dataBase=dbHelper.getWritableDatabase();
     return dataBase.delete(table, where, args);
 }

 @Override
 public String getType(Uri arg0) {
  // TODO Auto-generated method stub
  return null;
 }

 
 @Override
 public Uri insert(Uri uri, ContentValues initialValues) {
  String table = getTableName(uri);
  SQLiteDatabase database = dbHelper.getWritableDatabase();
  long value = database.insert(table, null, initialValues);
  return Uri.withAppendedPath(CONTENT_URI, String.valueOf(value));
 }

 @Override
 public Cursor query(Uri uri, String[] projection, String selection,
      String[] selectionArgs, String sortOrder) {
  String table =getTableName(uri);
  SQLiteDatabase database = dbHelper.getReadableDatabase();
  Cursor cursor =database.query(table,  projection, selection, selectionArgs, null, null, sortOrder);
     return cursor;
 }  

 @Override
 public int update(Uri uri, ContentValues values, String whereClause,
      String[] whereArgs) {
  String table = getTableName(uri);
  SQLiteDatabase database = dbHelper.getWritableDatabase();  
  return database.update(table, values, whereClause, whereArgs);
 }
 
 public static String getTableName(Uri uri){
  String value = uri.getPath();
  value = value.replace("/", "");//we need to remove '/'
  return value;
 }
}

Here OurDatabaseHelper is the database helper class (extends SQLiteOpenHelper )
getTableName is used to get the specific Table name

Don't forget to add this in your manifest.xml file
<provider android:authorities="ourContentProviderAuthorities"
 android:name=".ContentProviderDb">
We specify our AUTHORITY as android:authorities

So the db operation will be like this:

Uri contentUri = Uri.withAppendedPath(ContentProviderDb.CONTENT_URI, "TableName");
Using these contentUri we are specifying our table where we need to perform our operation

We can perform db operation using our context

context.getContentResolver().insert(.....);
context.getContentResolver().query(.....);
context.getContentResolver().delete(.....);
context.getContentResolver().update(.....);


And if you are inside an activity class

getContentResolver().insert(.....);
getContentResolver().query(.....);
getContentResolver().delete(.....);
getContentResolver().update(.....);

For an example an insert operation will look like this

ContentValues initialValues = new ContentValues();
initialValues.put("Column", "value");
Uri contentUri = Uri.withAppendedPath(ContentProviderDb.CONTENT_URI, "TableName");
Uri resultUri = context.getContentResolver().insert(contentUri, initialValues);

Hope this help.
And please feel free to point out my mistakes... 

8 comments:

  1. Hi i get java.lang.illegalargumentexception unknown url content // exception what might be the reason??

    ReplyDelete
  2. dbHelper = new DBHelper_Settings(this);
    newDB = dbHelper.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(Settings_CP.KEY,ipAddress.getText().toString()+"");
    this.getContentResolver().insert(Settings_CP.CONTENT_URI, values);

    this is the code for insertion

    ReplyDelete
    Replies
    1. What is the value you stored in the Settings_CP.CONTENT_URI, it should be some thing like Uri.parse("content://" + AUTHORITY/......)

      Delete
  3. when i use simplecursoradapter like this

    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item, cursor, FROM, TO);

    i always get this exception
    Caused by: java.lang.IllegalArgumentException column '_id' does not exist... can you tell me how to solve this

    ReplyDelete
  4. i am facing a tough time. i need to insert a new contact in android. i need proper procedure to insert a new contact in android database. please help me

    ReplyDelete
  5. Can you post example of how to share database in two applications in android using content provider.

    ReplyDelete
  6. I want to make an app on Online Test in Android. I'm not knowing which one to use either SQLite or any other database mechanism to store the answers and evaluate questions. Can you please tell me?

    ReplyDelete
  7. What should I write instead of AUTHORITY?

    ReplyDelete