Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Android Content Provider: How to use Content Provider for Data Access

In this article we will see the explanation of content provider and cursors for Data Access.

On the Android platform, all persistent data of an app is private to that app. This means that an app cannot query or manipulate the data of another app. However, if you want to enable an app to query or manipulate the data of another app, you need to use the concept of content providers.

A content provider acts as an interface that allows you to store and retrieve data from a data source. It also allows you to share an app’s data with other apps. Content providers decouple the app layer from the data layer by abstracting the underlying data source, thereby making apps data-source independent. They allow full permission control by monitoring which app components or users should have access to the data making data sharing easy. As a result, any app with appropriate permissions can add, remove, update, and retrieve data of another app including the data in some native Android databases.

The Android platform supports two types of content providers that can be used in your app:

  • Custom content providers: These are created by the developer to suit the requirements of an app.
  • Native content providers: These provide access to built-in databases, such as contact manager, media player, and other native databases. You need to grant the required permissions to your app before using native content providers.

Using Custom Content Providers

A custom content provider is created by a developer to enable sharing of the app’s data with other apps. To create a custom content provider, you have to perform the following steps:

  1. Create a custom content provider.
  2. Specify the URI of a content provider.
  3. Implement query handling methods.
  4. Access the data exposed by a content provider.
  5. Handle requests for the MIME type of data.
  6. Register a custom content provider.

Let us see how to create and access data through a custom content provider.

Creating a Custom Content Provider

To create your own content provider, you need to create a class that extends the abstract ContentProvider class and overrides its methods.

The following skeleton code displays the overridden methods of this class:

  public class ContactDetailsProvider extends ContentProvider
  { 
  @Override public int delete(Uri uri, String selection, String[] selectionArgs) 
  { 
  // TODO Auto-generated method stub. 
  return 0; 
  } 
  @Override public String getType(Uri uri) 
  { 
  // TODO Auto-generated method stub. 
  return null; 
  } 
  @Override public Uri insert(Uri uri, ContentValues values) 
  { 
  // TODO Auto-generated method stub 
  return null; 
  } 
  @Override public boolean onCreate() 
  { 
  // TODO Auto-generated method stub. 
  return false; 
  } 
  @Override public Cursor query(Uri uri, String[]projection, String selection, String[] selectionArgs, String sortOrder) 
  { 
  // TODO Auto-generated method stub .
  return null; 
  } 
  @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) 
  { 
  // TODO Auto-generated method stub.
  return 0; 
  } 
  }

In the preceding skeleton code, the following methods of the ContentProvider class have been overridden:

  • delete(): This method handles requests to delete records from the content provider.
  • getType(): This method handles requests for the MIME type of data for the given URI.
  • insert(): This method handles requests to insert a new row in the content provider.
  • onCreate(): This method is called when the content provider starts and is used to open or initialize the underlying data source.
  • query(): This method handles query requests from the client and returns a cursor object.
  • update(): This method handles requests to update existing records in a content provider.

Once a content provider has been created, you need to specify a URI that apps can use to access the content provider.

Specifying the URI of a Content Provider

Each content provider exposes a URI that uniquely identifies the content provider’s data set. If a content provider controls multiple datasets, a separate URI needs to be specified for each dataset. The URI of a content provider begins with the string, content://.

To expose the URI of a content provider, you need to declare it as a public static final variable named, CONTENT_URI, as shown in the following code snippet:

  public static final Uri CONTENT_URI = Uri.parse("content:// com.example.provider.myProvider/ myTable");

It is a good practice to specify your URI path according to your package name.

Every CONTENT_URI can be used in two ways. These are:

  • content://<package name>.provider.<custom content provider>/<table name>: Requests for all the values in the table.
  • content://<package name>.provider.<custom content provider>/<table name>/<position>: Requests for a single record available at a specific position.

To support access to your provider using both these forms, you need to use the UriMatcher class of the android.content package. You need to configure the object of the UriMatcher class to parse the URI’s form when the provider is accessed to retrieve or manipulate data, as shown in the following code snippet:

  public class MyCustomProvider extends ContentProvider 
  { 
  private static final String myURI = “content:// com.niit.provider.MyCustomProvider/ BookDetails"; 
  public static final Uri CONTENT_URI = Uri.parse(myURI); 
  @Override public int delete(Uri arg0, String arg1, String[] arg2) { 
  // TODO Auto-generated method stub. 
  return 0; 
  } 
  @Override public String getType(Uri arg0) 
  { 
  // TODO Auto-generated method stub.
  return null; 
  } 
  @Override public Uri insert(Uri arg0, ContentValues arg1) 
  { 
  // TODO Auto-generated method stub.
  return null; 
  } 
  @Override public boolean onCreate() 
  { 
  // TODO Auto-generated method stub. 
  return false; 
  } 
  @Override public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) 
  { 
  // TODO Auto-generated method stub. 
  return null; 
  } 
  @Override public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) 
  {
  // TODO Auto-generated method stub. 
  return 0; 
  } 
  // Create the constants used to differentiate between the different URI requests.
  private static final int ALLROWS = 1; 
  private static final int SINGLE_ROW = 2; 
  // You need to import android.content.UriMatcher. 
  private static final UriMatcher uriMatcher; 
  // Populate the UriMatcher object 
  }

The constants associated with the URI pattern can be used to check whether to perform an action on all records or on a specific record in a table. Once a content provider has been created and its URI has been specified, apps can start accessing data through the content provider.

Implementing Query Handling Methods

To handle queries to a content provider, you need to implement the delete(), insert(), update(), and query()methods in the class that extends from the ContentProvider class of the android.content package.

These methods allow an Android app to share the data across app boundaries even if you do not publish separate interfaces for each app. The following code snippet shows the implementation of delete, insert, select, and update queries for a custom content provider:

@Override public int delete(Uri arg0, String arg1, String[] arg2) { 
  switch (uriMatcher.match(arg0)) 
  { 
  // If the arg0 parameter contains the constant value ALLROWS
   // delete all records from the table. case ALLROWS: 
  // Code to delete all rows in the table 
  // If the arg0 parameter contains the constant value SINGLE_ROW // delete only the specified record from the table. case SINGLE_ROW:
   // Code to delete a single row in the table .
  default: 
  throw new IllegalArgumentException("URI not supported:" + arg0); 
  }
   }
   @Override public Uri insert(Uri arg0, ContentValues arg1)
  {
   // Add a new record into the table.
   Long rowID = SQLite_databaseName. Insert(table_name, "", values); 
  // If the record is successfully added .
  if (rowID > 0) 
  {
   /* Append the rowID at the end of the CONTENT_URI and return the resulting URI where CONTENT_URI is the URI for the content provider. */
   return ContentUris.withAppendedId (CONTENT_URI, rowID); 
  }
   throw new SQLException("Failed to add new item into " + arg0);
   } 
  @Override public boolean onCreate() 
  { 
  // TODO Auto-generated method stub.
   return false; 
  }
   @Override public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) 
  { 
  SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder(); 
  sqlBuilder.setTables(table_name); 
  // Retrieve records as specified by the query parameters.
   Cursor c = sqlBuilder.query (database_name, arg1, arg2, arg3, null, null, arg4); 
  return c; 
  } 
  @Override public int update(Uri arg0, ContentValues arg1, String arg2, String [] arg3) 
  { 
  switch (uriMatcher.match(arg0)) 
  { 
  case ALLROWS: // Code to update all rows in the table case .
  SINGLE_ROW: // Code to update a single row in the table 
  default: 
  throw new IllegalArgumentException("URI not supported:" + arg0); } }

Accessing the Data Exposed by a Content Provider

On the Android platform, all content providers use a common interface for querying the provider and returning results to a client app. Adding, modifying, and deleting data is also done from the same interface. To access data exposed by content providers, the android.content.ContentResolver class is used. Each Android app context consists of a single ContentResolver instance.

This instance can be accessed only by using the getContentResolver() method, as shown in the following code snippet: ContentResolver resolver = getContentResolver(); You can use the content resolver's method to interact with the content providers. When a query is initiated, the Android system identifies the targeted content provider and ensures that it is running.

Typically, there is a single instance of each type of content provider, which can communicate with multiple ContentResolver objects in different apps and processes. The interaction between these processes is handled by the ContentResolver and ContentProvider classes.

The following code snippet illustrates how to access the data exposed by a content provider:

ContentResolver cr = getContentResolver (); 
  Cursor cursor = cr.query (ContactsContract.Contacts.CONTENT_URI , null, "DISPLAY_NAME = '" + name + "'", null, null);
   if (cursor.moveToFirst()) 
  { 
  String contactId = cursor.getString (cursor.getColumnIndex (ContactsContract.Contacts._ID)); 
  String contactName = cursor.getString (cursor.getColumnIndex (ContactsContract.Contacts.DISPLAY_NAM E));

The preceding code snippet fetches details from the device’s contacts database.

Note: To retrieve records from a content provider, you either use the ContentResolver.query()method or the Activity.managedQuery()method. Both methods take the same set of arguments and return a Cursor object. However, the cursor returned by the Activity.managedQuery()method is a managedcursor whose lifecycle is managed by the activity.

Handling Requests of the MIME Type of Data

To handle request for the MIME type of data provided by the content provider, you need to override the getType()method in the class that extends the ContentProvider class. The getType()method takes a Uri object as a parameter and returns a string, which uniquely describes the MIME type of the URI. If the given URI is not supported by the content provider, an exception can be thrown or a null value can be returned. The type returned can take any of the following two forms:

  • vnd.android.cursor.item/ <contenttype>: Returns a single item for a single entry.
  • vnd.android.cursor.dir/ <contenttype>: Return all items for all the entries.

The following code illustrates how to implement the getType()method:

public String getType(Uri uri) 
  {
   int code = uriMatcher.match(uri); 
  switch (code) 
  { 
  case ALLROWS:
  return "vnd.android.cursor.dir/ BookDetails"; 
  case SINGLE_ROW:
  return "vnd.android.cursor.item/ BookDetails";
   default: 
  throw new IllegalArgumentException ("Unsupported URI: " + arg0); 
  }
   }

Note: An app does not require any permission to access the MIME type of data provided by a content provider.

Registering a Custom Content Provider

After creating a content provider, you must register it in your app’s manifest file. This informs the system about the custom content provider created. In the app’s manifest file, you need to declare the content provider within the <provider> element. If you do not declare your content provider, your content provider will not be visible to the Android system. The following markup illustrates the declaration of a custom content provider in the manifest file:

  <provider android:name="MyCustomProvider" android:authorities="com.DatabaseDemo. provider.MyCustomProvider"> </provider>

In the preceding markup, the name attribute refers to the qualified name of the custom content provider, a class that extends the ContentProvider class. The authorities attribute refers to the URI that identifies the data associated with the provider.

Using Native Content Providers

The android.provider class includes classes that simplify the use of various built-in native content providers of the Android platform. Some native content providers provided by the Android platform are:

  • Browser: This content provider allows you to access the data related to browser history, bookmarks, and Web searches.
  • Contacts: This content provider allows you to access and modify the native contact details database.
  • Call log: This content provider allows you to access data related to call history, including incoming calls, outgoing calls, missed calls, and received calls.
  • Media store: This content provider allows you to access the multimedia files stored on your device. It also allows you to store your own multimedia files including images, audio files, video files, and so on. It provides a centralized and a managed way to store and access media files on the device/emulator.
  • Settings: This content provider allows you to access and modify the device’s preferences including Bluetooth settings and ringtones.

All native content providers can be used wherever required, thereby ensuring that the apps created integrate seamlessly with other native and third-party apps. Native content providers expose a URI that registers the content provider. The following code snippet shows the various parts of the URI for the Contacts content provider: content://contacts/people/20 In the preceding code snippet:

  • content:// specifies that the data is controlled by a content provider. It is a standard prefix.
  • Contacts refers to the native Contacts content provider.
  • People refers to the records available in the contacts list.
  • 20 refers to the twentieth record in the contacts list. It is the ID of the specific record.

To use the native Contacts content provider in an app, your app must have the READ_CONTACTS permission and appropriate entry is made in the AndroidManifest.xml file .

The following code snippet explains how to access the contact details from the native Contacts content provider:

/* In the following statement, a cursor is initialized. It queries the built-in Contacts content provider. In the query method, the People.CONTENT_URI is a URI that retrieves all records of the people content provider into the cursor object */ 
  Cursor c = getContentResolver().query (People.CONTENT_URI, null, null, null, null); 
  // Retrieve the index of the name column available in the People URI.
   int name = c.getColumnIndexOrThrow (People.NAME); 
  // Retrieve the index of the phone number column available in the People URI.
  int ph = c. getColumnIndexOrThrow (People.NUMBER); 
  // Create an array to store the data available inside the cursor.
  String[] res = new String[c.getCount ()]; 
  if (c.moveToFirst()) 
  do 
  { 
  // Retrieve the name and phone number values using cursor objects and store it into string variables. 
  String Cname = c.getString(name); 
  String phone = c.getString(ph); 
  // Store the name and phone number string values into an array.
  res[c.getPosition()] = Cname + "(" + phone + ")"; 
  } 
  while(c.moveToNext()); 

In the preceding code snippet, a cursor is initialized and queries the built-in Contacts content provider. People.CONTENT_URI is used to retrieve all the records from the content provider in the cursor object. The getColumnIndexOrThrow()method retrieves the index of the NAME and NUMBER columns. As a result, an array is created to store the values of both columns using cursors.

Note : There is a new API and class (android.provider.ContactsContract.Contacts) for fetching contacts from the device’s contact database post Android platform API level 5. Though, fetching the same through the android.provider.Contacts.People class is still being supported.

Conclusion:

This is all about the cursors in android. This article explained everything about the concept of content provider. Android provides various ways to store and retrieve persistent app data, namely SQLite, internal storage, external storage, shared preferences, and network connection. When any query is executed, cursors are used to store the results of that query in rows. In Android, cursors act as a pointer to the subset of the underlying data. The Cursor interface includes various methods to navigate query results. Content providers act as an interface that allows you to share data between apps. In Android, all content providers use a common interface for querying the providers and returning results. Adding, updating, and deleting the data is also done from the same interface. To create your own content provider, you need to create a class that extends the abstract ContentProvider class and overrides its various methods. To access content providers, the ContentResolver class is used. After creating a content provider, you must add it to your app’s manifest file to make it visible to the system. If you require more help about content provider then please leave a comment.

Happy Learning! Happy Development!



Certified Trainer for Windows 8 Mobile App Development, IBM CE Project Trainer With IBM DB2, RAD, RSA, Certified Trainer for ZEND (PHP), Certified PHP and MySql trainer, Certified trainer of Diploma in Oracle 10g (DBA) as per Orac...

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login