I’ve been searching over internet to find out one good example for Custom Content Provider but found very little help in trying to run examples rightaway from web. Lots of examples are 1/2 done or 1/2 written. I wanted to come out with a runnign example and here is the example. Again as before i’ve compiled and modified this example from code i have found over web so that some UI is added to it.
Content providers store and retrieve data and make it accessible to all applications. They’re the only way to share data across applications; there’s no common storage area that all Android packages can access.
Each content provider exposes a public URI (wrapped as a Uri object) that uniquely identifies its data set. A content provider that controls multiple data sets (multiple tables) exposes a separate URI for each one. All URIs for providers begin with the string “content://”. The content: scheme identifies the data as being controlled by a content provider
Querying a Content Provider
You need three pieces of information to query a content provider:
The URI that identifies the provider
The names of the data fields you want to receive
The data types for those fields
If you’re querying a particular record, you also need the ID for that record.
Below is the code that creates content provider (Here content provider acts like a wrapper to sqllite database)
package com.linkwithweb.providers; import android.net.Uri; import android.provider.BaseColumns; /** * @author Ashwin Kumar * */ public class MyUsers { public static final String AUTHORITY = "com.linkwithweb.providers.MyContentProvider"; // BaseColumn contains _id. public static final class User implements BaseColumns { public static final Uri CONTENT_URI = Uri .parse("content://com.linkwithweb.providers.MyContentProvider"); // Table column public static final String USER_NAME = "USER_NAME"; } }
package com.linkwithweb.providers; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; 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; /** * @author Ashwin Kumar * */ public class MyContentProvider extends ContentProvider { private SQLiteDatabase sqlDB; private DatabaseHelper dbHelper; private static final String DATABASE_NAME = "Users.db"; private static final int DATABASE_VERSION = 1; private static final String TABLE_NAME = "User"; private static final String TAG = "MyContentProvider"; private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // create table to store user names db.execSQL("Create table " + TABLE_NAME + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, USER_NAME TEXT);"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } } @Override public int delete(Uri uri, String s, String[] as) { return 0; } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues contentvalues) { // get database to insert records sqlDB = dbHelper.getWritableDatabase(); // insert record in user table and get the row number of recently inserted record long rowId = sqlDB.insert(TABLE_NAME, "", contentvalues); if (rowId > 0) { Uri rowUri = ContentUris.appendId( MyUsers.User.CONTENT_URI.buildUpon(), rowId).build(); getContext().getContentResolver().notifyChange(rowUri, null); return rowUri; } throw new SQLException("Failed to insert row into " + uri); } @Override public boolean onCreate() { dbHelper = new DatabaseHelper(getContext()); return (dbHelper == null) ? false : true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); SQLiteDatabase db = dbHelper.getReadableDatabase(); qb.setTables(TABLE_NAME); Cursor c = qb.query(db, projection, selection, null, null, null, sortOrder); c.setNotificationUri(getContext().getContentResolver(), uri); return c; } @Override public int update(Uri uri, ContentValues contentvalues, String s, String[] as) { return 0; } }
Now lets create an Activity and Corresponding view to display this in GUI
/** * */ package com.linkwithweb; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.linkwithweb.providers.MyUsers; /** * @author Ashwin Kumar * */ public class CustomProviderDemo extends Activity { private EditText mContactNameEditText; private TextView mContactsText; private Button mContactSaveButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.custom_provider); // Obtain handles to UI objects mContactNameEditText = (EditText) findViewById(R.id.contactNameEditText); mContactSaveButton = (Button) findViewById(R.id.contactSaveButton); mContactsText = (TextView) findViewById(R.id.contactEntryText); mContactSaveButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { String name = mContactNameEditText.getText().toString(); insertRecord(name); mContactsText.append("\n"+name); } }); //insertRecord("MyUser"); displayRecords(); } private void insertRecord(String userName) { ContentValues values = new ContentValues(); values.put(MyUsers.User.USER_NAME, userName); getContentResolver().insert(MyUsers.User.CONTENT_URI, values); } private void displayRecords() { // An array specifying which columns to return. String columns[] = new String[] { MyUsers.User._ID, MyUsers.User.USER_NAME }; Uri myUri = MyUsers.User.CONTENT_URI; Cursor cur = managedQuery(myUri, columns, // Which columns to return null, // WHERE clause; which rows to return(all rows) null, // WHERE clause selection arguments (none) null // Order-by clause (ascending by name) ); if (cur.moveToFirst()) { String id = null; String userName = null; do { // Get the field values id = cur.getString(cur.getColumnIndex(MyUsers.User._ID)); userName = cur.getString(cur .getColumnIndex(MyUsers.User.USER_NAME)); Toast.makeText(this, id + " " + userName, Toast.LENGTH_LONG) .show(); } while (cur.moveToNext()); } } }
Below is the view code
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TableLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/contactNameLabel"/> </TableRow> <TableRow> <EditText android:id="@+id/contactNameEditText" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_weight="1"/> </TableRow> <TableRow> <Button android:layout_height="wrap_content" android:text="@string/save" android:id="@+id/contactSaveButton" android:layout_width="match_parent" android:layout_weight="1"/> </TableRow> <TableRow> <TextView android:text="@+id/contactEntryText" android:id="@+id/contactEntryText" android:layout_width="match_parent" android:layout_height="wrap_content"/> </TableRow> </TableLayout> </ScrollView>
Below is the configuration you can define in Manifest file
<activity android:name=".CustomProviderDemo" android:label="CustomProviderDemo"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity> <provider android:name="com.linkwithweb.providers.MyContentProvider" android:authorities="com.linkwithweb.providers.MyContentProvider" />
Code has been checked in to below url. You can checkout from the below svn url for workign code of whole project with all other lessons
https://linkwithweb.googlecode.com/svn/trunk/Android/AndroidLessons
A very nice working example. Thanks Ashwin.
Thank you for this tutorial. Unfortunately it is not working for me. I cannot get rid of “Failed to find provider info for MyContentProvider . It seems to be a simple issue, but all I found on google could not solve this problem. Do you have a solution for it / know, what could be wrong?
Thx in advance!!!
well, don’t know why, but after copying everything in an exactly the genuine way (excluding own authorities etc.) it works. Sorry, for bothering 🙂
[…] this link for custom content […]
[…] https://ashwinrayaprolu.wordpress.com/2011/03/16/custom-content-provider-in-android/ […]
I just wanted to just take a couple of seconds and let you know that I
appreciated the write-up. I honestly don’t think many people know how many hours of labor that gets put into having a post. I’m sure this is kind of random however it bugs me sometimes.
Anyhow good site.
Good example.. Saves time
excellent blog I’m a big football fan from germany
nice tutorial.. works perfectly.. but how to use this in another application.. means how to work with same database in another application ???
I want to use the same database in another application using custome content provider..
[…] is a sample tutorial for […]
[…] Outra opção é através do Custom Content Provider. […]