Introduction
In this article I explain what a content provider is. A content provider is a collection of information of which a provider uses a way to access itself using another application. For example Contacts is a content provider because whenever we text a message, we want to import a number from the contact, then the contact provides us access to itself through another app, smsApplication. But in this article I create my own content provider that will provide all the content that will be available in this content provider, as described in the following procedure.
Step 1
Create a new project as "File" -> "New" -> "Android Application Project" as shown below.
Step 2
Now open the XML file "res/layout/activity_main.xml" and update it as in the following code.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ISBN" />
<EditText
android:id="@+id/txtISBN"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Title" />
<EditText
android:id="@+id/txtTitle"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
<Button
android:text="Add title"
android:id="@+id/btnAdd"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:text="Retrieve titles"
android:id="@+id/btnRetrieve"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Step 3
Open Java from "src/com.newandroid.project/MainActivity.java" and update it with the following code.
package com.content_provider;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
ListView lv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ContentValues editedValues = new ContentValues();
editedValues.put(ContentDiary.TITLE, "Android Tips and Tricks");
getContentResolver().update(
Uri.parse(
"content://com.ContentDiary.provider.books/books/2"),
editedValues,
null,
null);
getContentResolver().delete(
Uri.parse("content://com.ContentDiary.provider.books/books/2"),
null, null);
getContentResolver().delete(
Uri.parse("content://com.ContentDiary.provider.books/books"),
null, null);
ListView lv=(ListView) findViewById(R.id.view);
Button btnAdd = (Button) findViewById(R.id.btnAdd);
btnAdd.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put("title", ((EditText) findViewById(R.id.txtTitle)).getText().toString());
values.put("isbn", ((EditText) findViewById(R.id.txtISBN)).getText().toString());
Uri uri = getContentResolver().insert(
Uri.parse("content://com.ContentDiary.provider.books/books"),
values);
Toast.makeText(getBaseContext(),uri.toString(), Toast.LENGTH_LONG).show();
}
});
Button btnRetrieve = (Button) findViewById(R.id.btnRetrieve);
btnRetrieve.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//---retrieve the titles---
Uri allTitles = Uri.parse(
"content://com.ContentDiary.provider.books/books");
Cursor c = managedQuery(allTitles, null, null, null, "title desc");
if (c.moveToFirst()) {
do{
Log.d("ContentProviders",
c.getString(c.getColumnIndex(
ContentDiary._ID)) + ", " +
c.getString(c.getColumnIndex(
ContentDiary.TITLE)) + ", " +
c.getString(c.getColumnIndex(
ContentDiary.ISBN)));
} while (c.moveToNext());
}
}
});
}
}
Step 5
Create a new Java file "ContentDairy.java" as "src/com.content_provider/ContentDairy.java" and update it using the following code.
package com.content_provider;
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;
public class ContentDiary extends ContentProvider
{
public static final String PROVIDER_NAME =
"com.ContentDiary.provider.books";
public static final Uri CONTENT_URI =
Uri.parse("content://"+ PROVIDER_NAME + "/books");
public static final String _ID = "_id";
public static final String TITLE = "title";
public static final String ISBN = "isbn";
private static final int BOOKS = 1;
private static final int BOOK_ID = 2;
private static final UriMatcher uriMatcher;
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME, "books", BOOKS);
uriMatcher.addURI(PROVIDER_NAME, "books/#", BOOK_ID);
}
//---for database use---
private SQLiteDatabase booksDB;
private static final String DATABASE_NAME = "Books";
private static final String DATABASE_TABLE = "titles";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
"create table " + DATABASE_TABLE +
" (_id integer primary key autoincrement, "
+ "title text not null, isbn text not null);";
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion) {
Log.w("Content provider database",
"Upgrading database from version " +
oldVersion + " to " + newVersion +
", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS titles");
onCreate(db);
}
}
@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
// arg0 = uri
// arg1 = selection
// arg2 = selectionArgs
int count=0;
switch (uriMatcher.match(arg0)){
case BOOKS:
count = booksDB.delete(
DATABASE_TABLE,
arg1,
arg2);
break;
case BOOK_ID:
String id = arg0.getPathSegments().get(1);
count = booksDB.delete(
DATABASE_TABLE,
_ID + " = " + id +
(!TextUtils.isEmpty(arg1) ? " AND (" +
arg1 + ')' : ""),
arg2);
break;
default: throw new IllegalArgumentException("Unknown URI " + arg0);
}
getContext().getContentResolver().notifyChange(arg0, null);
return count;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)){
//---get all books---
case BOOKS:
return "vnd.android.cursor.dir/vnd.learn2develop.books ";
//---get a particular book---
case BOOK_ID:
return "vnd.android.cursor.item/vnd.learn2develop.books ";
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
//---add a new book---
long rowID = booksDB.insert(
DATABASE_TABLE,
"",
values);
//---if added successfully---
if (rowID>0)
{
Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(_uri, null);
return _uri;
}
throw new SQLException("Failed to insert row into " + uri);
}
@Override
public boolean onCreate() {
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
booksDB = dbHelper.getWritableDatabase();
return (booksDB == null)? false:true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
sqlBuilder.setTables(DATABASE_TABLE);
if (uriMatcher.match(uri) == BOOK_ID)
//---if getting a particular book---
sqlBuilder.appendWhere(
_ID + " = " + uri.getPathSegments().get(1));
if (sortOrder==null || sortOrder=="")
sortOrder = TITLE;
Cursor c = sqlBuilder.query(
booksDB,
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
//---register to watch a content URI for changes---
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)){
case BOOKS:
count = booksDB.update(
DATABASE_TABLE,
values,
selection,
selectionArgs);
break;
case BOOK_ID:
count = booksDB.update(
DATABASE_TABLE,
values,
_ID + " = " + uri.getPathSegments().get(1) +
(!TextUtils.isEmpty(selection) ? " AND (" +
selection + ')' : ""),
selectionArgs);
break;
default: throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
Step 6
Open and update the "AndroidManifest.xml" file from "res/AndroidManifest.xml" and update it as given below.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.content_provider"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.content_provider.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider android:name="ContentDiary"
android:authorities="com.ContentDiary.provider.books" />
</application>
</manifest>
Step 7
See the output:
You can use the URI "content://com.contentDAiry.provider.books/books/5" in another application.