YouTip LogoYouTip

Android Content Providers

The Content Provider component provides data from one application to other applications upon request. These requests are handled by the methods of the ContentResolver class. A content provider can store data in different ways. Data can be stored in a database, files, or even over the network. ![Image 1: Image](#) Sometimes, data needs to be shared between applications. This is where content providers become very useful. Content providers allow data to be centralized and accessed by multiple different applications when necessary. The behavior of a content provider is similar to a database. You can query and edit its content, using insert(), update(), delete(), and query() to add or remove content. In most cases, data is stored in an SQLite database. Content providers are implemented as subclasses of the ContentProvider class. A set of standard APIs must be implemented so that other applications can perform transactions. public class MyApplication extends ContentProvider {} * * * ## Content URI To query a content provider, you need to specify the query string in the form of a URI with the following format: ://// Here are the specific details of each part of the URI: | Part | Description | | --- | --- | | prefix | Prefix: Always set to content:// | | authority | Authority: Specifies the name of the content provider, such as Contacts, Browser, etc. Third-party content providers can be fully qualified names, like: cn.programmer.statusprovider | | data_type | Data Type: Indicates the type of data in this particular content provider. For example: To get all contacts through the Contacts content provider, the data path is people, so the URI would be: content://contacts/people | | id | This specifies a particular record to request. For example: To find a contact with ID 5 in the Contacts content provider, the URI would look like: content://contacts/people/5 | * * * ## Creating a Content Provider This section describes the simple steps to create your own content provider. * First, you need to create a content provider class by extending the ContentProvider base class. * Second, you need to define the URI address for your content provider that will be used to access the content. * Next, you need to create a database to store the content. Typically, Android uses SQLite databases, and you override the onCreate() method in the framework to create or open the provider's database using SQLiteOpenHelper methods. When your application starts, the onCreate() method of each of its content providers will be called on the application's main thread. * Finally, register the content provider in the AndroidManifest.xml file using the tag. Here are some of the methods you need to override in the ContentProvider class to make your content provider work properly: ![Image 2: Image](#) * onCreate(): Called when the provider is started. * query(): This method accepts requests from clients. The result is returned as a Cursor object. * insert(): This method inserts new records into the content provider. * delete(): This method deletes existing records from the content provider. * update(): This method updates existing records in the content provider. * getType(): This method returns the MIME type for the given URI. * * * ## Example This example explains how to create your own content provider. Let's follow the steps below: | Step | Description | | --- | --- | | 1 | Create an Android application using Android Studio and name it Content Provider, under the package com..contentprovider, and create an empty activity. | | 2 | Modify the main activity file MainActivity.java to add two new methods: onClickAddName() and onClickRetrieveStudents(). | | 3 | Create a new Java file StudentsProvider.java under the package com..contentprovider to define the actual provider and associate the methods. | | 4 | Register the content provider in the AndroidManifest.xml file using the tag. | | 5 | Modify the default content of the res/layout/activity_main.xml file to include a simple interface for adding student records. | | 6 | No need to modify strings.xml; Android Studio will handle the strings.xml file. | | 7 | Start the Android emulator to run the application and verify the results of the changes made by the application. | Below is the content of the modified main activity file src/com..contentprovider/MainActivity.java. This file contains each basic lifecycle method. We have added two new methods, onClickAddName() and onClickRetrieveStudents(), to allow the application to handle user interaction. package com..contentprovider;import android.net.Uri;import android.os.Bundle;import android.app.Activity;import android.content.ContentValues;import android.content.CursorLoader;import android.database.Cursor;import android.view.Menu;import android.view.View;import android.widget.EditText;import android.widget.Toast;import com..contentprovider.R;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } public void onClickAddName(View view) { // Add a new student record ContentValues values = new ContentValues(); values.put(StudentsProvider.NAME, ((EditText)findViewById(R.id.editText2)).getText().toString()); values.put(StudentsProvider.GRADE, ((EditText)findViewById(R.id.editText3)).getText().toString()); Uri uri = getContentResolver().insert( StudentsProvider.CONTENT_URI, values); Toast.makeText(getBaseContext(), uri.toString(), Toast.LENGTH_LONG).show(); } public void onClickRetrieveStudents(View view) { // Retrieve student records String URL = "content://com.example.provider.College/students"; Uri students = Uri.parse(URL); Cursor c = managedQuery(students, null, null, null, "name"); if (c.moveToFirst()) { do{ Toast.makeText(this, c.getString(c.getColumnIndex(StudentsProvider._ID)) + ", " + c.getString(c.getColumnIndex( StudentsProvider.NAME)) + ", " + c.getString(c.getColumnIndex( StudentsProvider.GRADE)), Toast.LENGTH_SHORT).show(); } while (c.moveToNext()); } }} Create a new file StudentsProvider.java under the package com..contentprovider. Below is the content of src/com..contentprovider/StudentsProvider.java. package com..contentprovider;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;public class StudentsProvider extends ContentProvider { static final String PROVIDER_NAME = "com.example.provider.College"; static final String URL = "content://" + PROVIDER_NAME + "/students"; static final Uri CONTENT_URI = Uri.parse(URL); static final String _ID = "_id"; static final String NAME = "name"; static final String GRADE = "grade"; private static HashMap STUDENTS_PROJECTION_MAP; static final int STUDENTS = 1; static final int STUDENT_ID = 2; static final UriMatcher uriMatcher; static{ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(PROVIDER_NAME, "students", STUDENTS); uriMatcher.addURI(PROVIDER_NAME, "students/#", STUDENT_ID); } /** * Database specific constants declaration */ private SQLiteDatabase db; static final String DATABASE_NAME = "College"; static final String STUDENTS_TABLE_NAME = "students"; static final int DATABASE_VERSION = 1; static final String CREATE_DB_TABLE = " CREATE TABLE " + STUDENTS_TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + " name TEXT NOT NULL, " + " grade TEXT NOT NULL);"; /** * Helper class that manages the provider's internal data source. */ 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_DB_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + STUDENTS_TABLE_NAME); onCreate(db); } } @Override public boolean onCreate() { Context context = getContext(); DatabaseHelper dbHelper = new DatabaseHelper(context); /** * Create a writable database if it doesn't exist. */ db = dbHelper.getWritableDatabase(); return (db == null)? false:true; } @Override public Uri insert(Uri uri, ContentValues values) { /** * Add a new student record */ long rowID = db.insert( STUDENTS_TABLE_NAME, "", values); /** * If record added successfully */ if (rowID > 0) { Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID); getContext().getContentResolver().notifyChange(_uri, null); return _uri; } throw new SQLException("Failed to add a record into " + uri); } @Override public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); qb.setTables(STUDENTS_TABLE_NAME); switch (uriMatcher.match(uri)) { case STUDENTS: qb.setProjectionMap(STUDENTS_PROJECTION_MAP); break; case STUDENT_ID: qb.appendWhere( _ID + "=" + uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } if (sortOrder == null || sortOrder == ""){ /** * Sort by student name by default */ sortOrder = NAME; } Cursor c = qb.query(db, projection, selection, selectionArgs,null, null, sortOrder); /** * Register a listener for content URI changes */ c.setNotificationUri(getContext().getContentResolver(), uri); return c; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int count = 0; switch (uriMatcher.match(uri)){ case STUDENTS: count = db.delete(STUDENTS_TABLE_NAME, selection, selectionArgs); break; case STUDENT_ID: String id = uri.getPathSegments().get(1); count = db.delete( STUDENTS_TABLE_NAME, _ID + " = " + id + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int count = 0; switch (uriMatcher.match(uri)){ case STUDENTS: count = db.update(STUDENTS_TABLE_NAME, values, selection, selectionArgs); break; case STUDENT_ID: count = db.update(STUDENTS_TABLE_NAME, 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; } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)){ /** * Get all student records */ case STUDENTS: return "vnd.android.cursor.dir/vnd.example.students"; /** * Get a specific student */ case STUDENT_ID: return "vnd.android.cursor.item/vnd.example.students"; default: throw new IllegalArgumentException("Unsupported URI: " + uri); } }} Below is the modified AndroidManifest.xml file. Here, the tag has been added to include our content provider: Below is the content of the res/layout/activity_main.xml file:
← Android Single FragmentGo If Statement β†’