THIS CONTENT DOWNLOAD SHORTLY

Objective

The main objective of this tutorial is to guide you on creating a custom content provider.

 

You will get Final Output:

  • content-provider-demo11
  • content-provider-demo21
 

Step 1 Introduction

Content Providers are used to manage the access over the set of data. They provide mechanisms for defining data security and for encapsulating the data. Content Providers act as an interface for connecting data of one application to that with another application.

To use content provider, you need to use ContentResolver object in your application’s context which is then used to communicate with the provider.

You need to develop your own Provider if:

  1. You want to share your data with other applications.
  2. You want to provide custom search suggestions in your own application.

You need to use your own providers if you want to copy and paste complex data.

 

Step 2 Create Content Provider

The ContentProvider class is the main factor of a content provider.

To create a content provider we have to:

  1. Make subclass for ContentProvider.
  2. Define content URI in the class.
  3. Implement all unimplemented methods: insert(), update(), query(), delete(), getType().
  4. Declare content provider in AndroidManifest.xml

Important URI: Content provider URI contains four parts. content: //authority/path/id

content: // All the content provider URIs must start with this value.
authority It is Java namespace of content provider implementation.
path It is the simulated directory inside the provider that categorizes the kind of data being requested.
id It is an elective part that details the primary key of a record being requested. We can neglect this part to request all the records.

To learn more about ContentProvider methods, visit the following link:

 

Step 3 Registering the provider in AndroidManifest.xml

Like any other main portions of Android application, we need to register the content providers too in the AndroidManifest.xml. <provider> part is used to register the content providers. <application> is its parent component.

<providerandroid:name="com.tag.custom_contentproviderdemo.PlatesContentProvider"
android:authorities="com.tag.custom_contentproviderdemo.Plates">
</provider>

Here, authorities is the URI authority to access the content provider. Usually, this will be the fully certified name of the content provider class.

Example Application:

In this example, we are working on creating an application which creates content provider to share data with another application.

The URI of this content provider is: "content://" + AUTHORITY + "/plates"

 

Step 4 PlatesData.java

Create PlatesData.java file and write the following content in that class.

publicclass PlatesData {
 
    public PlatesData() {
 
    }
 
    // A content URI is a URI that identifies data in a provider. Content URIs
    // include the symbolic name of the entire provider (its authority)
    publicstaticfinal String AUTHORITY = "com.tag.custom_contentproviderdemo.Plates";
    publicstaticfinal Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
            + "/plates");
 
    publicstaticfinal String DATABASE_NAME = "plates.db";
    publicstaticfinalintDATABASE_VERSION = 1;
 
    publicstaticfinal String CONTENT_TYPE_PLATES = "vnd.android.cursor.dir/vnd.tag.plates";
    publicstaticfinal String CONTENT_TYPE_PLATE = "vnd.android.cursor.item/vnd.tag.plate";
 
    publicclass Plates implements BaseColumns {
 
        private Plates() {
 
        }
 
        publicstaticfinal String TABLE_NAME = "plates";
 
        publicstaticfinal String _ID = "_id";
        publicstaticfinal String _TITLE = "title";
        publicstaticfinal String _CONTENT = "content";
    }
}
 

Step 5 PlatesContentProvider.java

Create PlatesContentProvider.java file and write the following content in that class.

publicclass PlatesContentProvider extends ContentProvider {
 
    privatestaticfinal UriMatcher sUriMatcher;
 
    privatestaticfinalintNOTES_ALL = 1;
    privatestaticfinalintNOTES_ONE = 2;
 
    static {
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sUriMatcher.addURI(PlatesData.AUTHORITY, "plates", NOTES_ALL);
        sUriMatcher.addURI(PlatesData.AUTHORITY, "plates/#", NOTES_ONE);
    }
 
    // Map table columns
    privatestaticfinal HashMap<String, String>sNotesColumnProjectionMap;
    static {
        sNotesColumnProjectionMap = new HashMap<String, String>();
        sNotesColumnProjectionMap.put(PlatesData.Plates._ID,
                PlatesData.Plates._ID);
        sNotesColumnProjectionMap.put(PlatesData.Plates._TITLE,
                PlatesData.Plates._TITLE);
        sNotesColumnProjectionMap.put(PlatesData.Plates._CONTENT,
                PlatesData.Plates._CONTENT);
    }
 
    privatestaticclass NotesDBHelper extends SQLiteOpenHelper {
 
        public NotesDBHelper(Context c) {
            super(c, PlatesData.DATABASE_NAME, null,
                    PlatesData.DATABASE_VERSION);
        }
 
        privatestaticfinal String SQL_QUERY_CREATE = "CREATE TABLE "
                + PlatesData.Plates.TABLE_NAME + " (" + PlatesData.Plates._ID
                + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + PlatesData.Plates._TITLE + " TEXT NOT NULL, "
                + PlatesData.Plates._CONTENT + " TEXT NOT NULL" + ");";
 
        @Override
        publicvoid onCreate(SQLiteDatabase db) {
            db.execSQL(SQL_QUERY_CREATE);
        }
 
        privatestaticfinal String SQL_QUERY_DROP = "DROP TABLE IF EXISTS "
                + PlatesData.Plates.TABLE_NAME + ";";
 
        @Override
        publicvoid onUpgrade(SQLiteDatabase db, intoldVer, intnewVer) {
            db.execSQL(SQL_QUERY_DROP);
            onCreate(db);
        }
    }
 
    // create a db helper object
    private NotesDBHelper mDbHelper;
 
    @Override
    publicboolean onCreate() {
        mDbHelper = new NotesDBHelper(getContext());
        returnfalse;
    }
 
    @Override
    publicint delete(Uri uri, String where, String[] whereArgs) {
        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        intcount = 0;
        switch (sUriMatcher.match(uri)) {
        caseNOTES_ALL:
            count = db.delete(PlatesData.Plates.TABLE_NAME, where, whereArgs);
            break;
 
        caseNOTES_ONE:
            String rowId = uri.getPathSegments().get(1);
            count = db.delete(
                    PlatesData.Plates.TABLE_NAME,
                    PlatesData.Plates._ID
                            + " = "
                            + rowId
                            + (!TextUtils.isEmpty(where) ? " AND (" + where
                                    + ")" : ""), whereArgs);
            break;
 
        default:
            thrownew IllegalArgumentException("Unknown URI: " + uri);
        }
 
        getContext().getContentResolver().notifyChange(uri, null);
        returncount;
    }
 
    @Override
    public String getType(Uri uri) {
 
        switch (sUriMatcher.match(uri)) {
        caseNOTES_ALL:
            return PlatesData.CONTENT_TYPE_PLATES;
 
        caseNOTES_ONE:
            return PlatesData.CONTENT_TYPE_PLATE;
 
        default:
            thrownew IllegalArgumentException("Unknown URI: " + uri);
        }
    }
 
    @Override
    public Uri insert(Uri uri, ContentValues values) {
 
        // you cannot insert a bunch of values at once so throw exception
        if (sUriMatcher.match(uri) != NOTES_ALL) {
            thrownew IllegalArgumentException(" Unknown URI: " + uri);
        }
 
        // Insert once row
        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        longrowId = db.insert(PlatesData.Plates.TABLE_NAME, null, values);
        if (rowId> 0) {
            Uri notesUri = ContentUris.withAppendedId(PlatesData.CONTENT_URI,
                    rowId);
            getContext().getContentResolver().notifyChange(notesUri, null);
            returnnotesUri;
        }
        thrownew IllegalArgumentException("<Illegal>Unknown URI: " + uri);
    }
 
    // Get values from Content Provider
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        switch (sUriMatcher.match(uri)) {
        caseNOTES_ALL:
            builder.setTables(PlatesData.Plates.TABLE_NAME);
            builder.setProjectionMap(sNotesColumnProjectionMap);
            break;
 
        caseNOTES_ONE:
            builder.setTables(PlatesData.Plates.TABLE_NAME);
            builder.setProjectionMap(sNotesColumnProjectionMap);
            builder.appendWhere(PlatesData.Plates._ID + " = "
                    + uri.getLastPathSegment());
            break;
 
        default:
            thrownew IllegalArgumentException("Unknown URI: " + uri);
        }
 
        SQLiteDatabase db = mDbHelper.getReadableDatabase();
        Cursor queryCursor = builder.query(db, projection, selection,
                selectionArgs, null, null, null);
        queryCursor.setNotificationUri(getContext().getContentResolver(), uri);
 
        returnqueryCursor;
    }
 
    @Override
    publicint update(Uri uri, ContentValues values, String where,
            String[] whereArgs) {
 
        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        intcount = 0;
        switch (sUriMatcher.match(uri)) {
        caseNOTES_ALL:
            count = db.update(PlatesData.Plates.TABLE_NAME, values, where,
                    whereArgs);
            break;
 
        caseNOTES_ONE:
            String rowId = uri.getLastPathSegment();
            count = db
                    .update(PlatesData.Plates.TABLE_NAME,
                            values,
                            PlatesData.Plates._ID
                                    + " = "
                                    + rowId
                                    + (!TextUtils.isEmpty(where) ? " AND ("
                                            + ")" : ""), whereArgs);
 
        default:
            thrownew IllegalArgumentException("Unknown URI: " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        returncount;
    }
}
 

Step 6 Add_plates.xml file

Take a layout to insert new records to the database table and to delete records from the database table.

<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
 
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/layout_pad">
 
<TextView
android:id="@+id/tvAddPlateTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title"
android:textAppearance="?android:attr/textAppearanceMedium"/>
 
<EditText
android:id="@+id/etAddPlateTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/edt_corner"
android:ems="10"
android:padding="@dimen/et_pad">
 
<requestFocus/>
</EditText>
</LinearLayout>
 
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/layout_pad">
 
<TextView
android:id="@+id/tvItemContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/content"
android:textAppearance="?android:attr/textAppearanceMedium"/>
 
<EditText
android:id="@+id/etAddPlateContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/edt_corner"
android:ems="10"
android:padding="@dimen/et_pad"/>
 
</LinearLayout>
 
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
 
<Button
android:id="@+id/btnAddPlateSubmit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/Add">
</Button>
</LinearLayout>
 
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
 
<Button
android:id="@+id/btnAddPlateDelete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/delete"/>
 
</LinearLayout>
 
</LinearLayout>
 

Step 7 Addplate.java file

Create Addplate.java file and write the following content in that class.

publicclass AddPlate extends Activity implements OnClickListener {
 
    private EditText etAddTitle, etAddContent;
    private Button btnAdd, btnDelete;
    private String _ID, _TITLE, _CONTENT;
    HashMap<String, String>map;
 
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_plate);
        setWidgetReference();
        bindWidgetEvents();
        getDataFromBundle();
    }
 
    privatevoid setWidgetReference() {
        etAddTitle = (EditText) findViewById(R.id.etAddPlateTitle);
        etAddContent = (EditText) findViewById(R.id.etAddPlateContent);
        btnAdd = (Button) findViewById(R.id.btnAddPlateSubmit);
        btnDelete = (Button) findViewById(R.id.btnAddPlateDelete);
    }
 
    @SuppressWarnings("unchecked")
    privatevoid getDataFromBundle() {
        map = (HashMap<String, String>) getIntent().getSerializableExtra(
                Constants.TAG_MAP);
        if (map != null) {
            System.out.println("mapdata" + map.get(Constants.TAG_TITLE));
            etAddTitle.setText(map.get(Constants.TAG_TITLE));
            etAddContent.setText(map.get(Constants.TAG_CONTENT));
            btnAdd.setText("Update");
        }
 
    }
 
    privatevoid bindWidgetEvents() {
        btnAdd.setOnClickListener(this);
        btnDelete.setOnClickListener(this);
    }
 
    void updatePlate(String str_id) {
        try {
            intid = Integer.parseInt(str_id);
            ContentValues values = new ContentValues();
            values.put(Plates._TITLE, etAddTitle.getText().toString());
            values.put(Plates._CONTENT, etAddContent.getText().toString());
            getContentResolver().update(PlatesData.CONTENT_URI, values,
                    PlatesData.Plates._ID + " = " + id, null);
            startActivity(new Intent(this, PlatesList.class));
            finish();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    privateboolean isValid() {
        if (etAddTitle.getText().toString().length() > 0) {
            if (etAddContent.getText().toString().length() > 0) {
                returntrue;
            } else {
                etAddContent.setError("Enter Content");
            }
        } else {
            etAddContent.setError("Enter Title");
        }
        returnfalse;
    }
 
    void deletePlate(String str_id) {
        try {
            intid = Integer.parseInt(str_id);
            getContentResolver().delete(PlatesData.CONTENT_URI,
                    PlatesData.Plates._ID + " = " + id, null);
            startActivity(new Intent(this, PlatesList.class));
            finish();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    privatevoid addPlateToDB() {
        if (isValid()) {
            ContentValues values = new ContentValues();
            values.put(Plates._TITLE, etAddTitle.getText().toString());
            values.put(Plates._CONTENT, etAddContent.getText().toString());
            getContentResolver().insert(PlatesData.CONTENT_URI, values);
            startActivity(new Intent(this, PlatesList.class));
            finish();
        }
    }
 
    @Override
    publicvoid onClick(View v) {
        if (v == btnAdd) {
            if (btnAdd.getText().equals("Update")) {
                updatePlate(map.get(Constants.TAG_ID));
            } else {
                addPlateToDB();
            }
 
        } elseif (v == btnDelete) {
            deletePlate(map.get(Constants.TAG_ID));
        }
    }
}
 

Step 8 AndroidManifest.xml File

Declare ContentProvider in AndroidManifest.xml File

<?xmlversion="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.tag.custom_contentproviderdemo"
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.tag.custom_contentproviderdemo.PlatesList"
android:label="@string/app_name">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
 
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- <activity android:name="com.tag.custom_contentproviderdemo.PlatesList" /> -->
<activityandroid:name="com.tag.custom_contentproviderdemo.AddPlate" />
 
<provider
android:name="com.tag.custom_contentproviderdemo.PlatesContentProvider"
android:authorities="com.tag.custom_contentproviderdemo.Plates">
</provider>
</application>
 
</manifest>

I hope this blog post will help you while working with Custom Content Provider in Android App. Let me know in a comment if you have any questions regarding Custom Content Provider in android app. I will reply you ASAP.

Got an Idea of Android App Development? What are you still waiting for? Contact us now and see the Idea live soon. Our company has been named as one of the best Android App Development Company in India.

I am professional Android application developer with experience of 1 years in Android Application Development. I worked with so many technology but android is the only one which interests me.