Android Content Provider in Kotlin

Have you ever wonder whenever you add some new contact in your contact application, then how that new contact gets included in your WhatsApp application? The contacts app is responsible for managing all your contacts and these contacts can be shared with other applications that are present in the Android device(if permission is taken). This is done with the help of Content Providers of an Application. In this blog, we will learn about Content Providers in Android.

What is an Android Content Provider?

Content Providers are used to share data of one application with other application in Android. For example, the details of contacts stored in your mobile device with the help of Contacts application is shared with other applications like WhatsApp, Facebook, etc. Here, the Contacts application is the provider and WhatsApp, Facebook is the client of your provider.

The application that is providing data i.e. the provider and the application that is using that data share a standard interface that is used for proper inter-process communication and for data sharing.

Some of the usages of content providers are:

  • You can share access to your application with some other applications.
  • You can send data to a widget.
  • You can load the data in your UI with the help of CursorLoader.
  • Can return custom search suggestions for your application

With the help of Content Provider, you can either use other application's data or you can share your application's data with other applications. We have a class called ContentResolver, which helps us to manage the requests of data. Content Provider responds with the data in the cursor format and the data that is given by the provider is in the form of one or more tables(containing rows and columns) where a row represents an instance of some kind of data and a column represents an individual piece of data collected for an instance.

So, let's learn how to access a provider with the help of ContentResolver.

Accessing Content Provider

In order to access the data that is provided by Content Provider of some application, you need to use the ContentResolver class. The object of ContentResolver communicates with the provider object and the provider object receives the data request from the client and the requested actions are being performed and finally, the result is returned. Let's learn how to use this.

To get the data provided by the Content Provider, we need to use the contentResolver().query() method. Following is the code for the same:

// Queries the user dictionary and returns results
cursor = contentResolver.query(
        UserDictionary.Words.CONTENT_URI,   // The content URI of the words table
        projection,                         // The columns to return for each row
        selectionClause,                    // Selection criteria
        selectionArgs.toTypedArray(),       // Selection criteria
        sortOrder                           // The sort order for the returned rows
)

The terms that are used in the above query are:

  • UserDictionary: It is an Android built-in provider that provides the words that user want to keep in the dictionary for future use. You can use other Content Provider here.
  • CONTENT_URI: It is the URI that identifies the data in a provider. In our case, it contains the URI of UserDictionary table. One of the examples of content URI can be:
content://user_dictionary/words
  • Projection: It is an array of columns that must be included in the retrieved rows. For example, if you want to include only 3 columns of the table, then your projection can be:
private val mProjection: Array<String> = arrayOf(
        UserDictionary.Words.COLUMN1,  
        UserDictionary.Words.COLUMN2, 
        UserDictionary.Words.COLUMN3  
)
  • Selection: It specifies the condition that is used for selecting rows.
  • SelectionArgs: It is used to replace the "?" placeholder in the selection clause.

For example,

// Defines a string to contain the selection clause
private var selectionClause: String? = null

// Declares an array to contain selection arguments
private lateinit var selectionArgs: Array<String>
  • SortOrder: It specifies the order in which the row should be displayed.
  • Cursor: Content Provider responds with the data in the cursor format. By using the Cursor methods, you can iterate over the rows in the result, get the data of the column, get the data type of each column, etc. If the result is nothing, then
Cursor.getCount() is 0

A cursor returns a list of rows. So, it is better to store the cursor result in some ListView.

// Defines a list of columns to retrieve from the Cursor and load into an output row
val wordListColumns : Array<String> = arrayOf(
        UserDictionary.Words.COLUMN1,      
        UserDictionary.Words.COLUMN2     
)

// Defines a list of View IDs that will receive the Cursor columns for each row
val wordListItems = intArrayOf(R.id.dictWord, R.id.locale)

// Creates a new SimpleCursorAdapter
cursorAdapter = SimpleCursorAdapter(
        applicationContext,              // The application's Context object
        R.layout.wordlistrow,            // A layout in XML for one row in the ListView
        mCursor,                         // The result from the query
        wordListColumns,                 // A string array of column names in the cursor
        wordListItems,                   // An integer array of view IDs in the row layout
        0                                // Flags (usually none are needed)
)

// Sets the adapter for the ListView(wordList is a ListView here)
wordList.setAdapter(cursorAdapter)

This is how you can get the data from a content provider of an application. Hope, you learned something new today.

Happy Learning :)

Team MindOrks!