Methods of Content Provider
- onCreate() When the receiver is formed, this function in Android initializes the Provider.
- query() In Android, it receives a query request from the user and responds with a cursor.
- insert() We use this method to insert data into our content provider.
- update() This function updates existing data in a row and returns the updated row data.
- delete() Removes existing data from the content provider.
- getType() This function returns the Multipurpose Internet Mail Extension data type to the supplied Content URI.
Content URI
The universal resource identifiers (URIs) that identify the data in content providers are known as Content URIs. A content URI contains two elements: Authority, which is the symbolic name of the Provider, and Path, which is a name that leads to the data. Every content provider method takes a URI as an argument.
Syntax
content://<authority>/<path>/<optional_id>
- content:// – It is always present and serves as the scheme portion of the URI.
- authority – It is the content provider's unique name, such as photos or contacts. It's a string that can identify the complete content source.
- path – It is frequently used to identify some or all of the Provider's data. The path is usually used to distinguish between specific tables.
- optional id - id is used to retrieve a specific record in a file. We only utilize this when we need to retrieve a particular document rather than the entire file. It is a numerical identification used to access a specific data table row.
Content Provider Implementation
We'll make a file called ContentProvider, and under it, a Java file called YourProvider.kt.
Code
package com.codingninjas.contentprovider
import android.content.*
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteException
import android.database.sqlite.SQLiteOpenHelper
import android.database.sqlite.SQLiteQueryBuilder
import android.net.Uri
class YourProvider : ContentProvider() {
companion object {
private const val PROVIDER_NAME = "com.codingninjas.contentprovider.UserProvider"
private const val URL = "content://$PROVIDER_NAME/users"
val CONTENT_URI: Uri = Uri.parse(URL)
const val id = "id"
const val uriCode = 1
var uriMatcher: UriMatcher? = null
private val values: HashMap<String, String>? = null
const val DATABASE_NAME = "EmpDB"
const val TABLE_NAME = "Employees"
const val DATABASE_VERSION = 1
const val CREATE_DB_TABLE = (" CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " name TEXT NOT NULL);")
init {
uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
uriMatcher!!.addURI(PROVIDER_NAME, "users", uriCode)
uriMatcher!!.addURI(PROVIDER_NAME, "users/*", uriCode)
}
}
override fun getType(uri: Uri): String {
if (uriMatcher!!.match(uri) == uriCode) {
return "cn.android.dir/usersData"
}
throw IllegalArgumentException("Unsupported URI: $uri")
}
override fun onCreate(): Boolean {
val context = context
val dbHelper = DatabaseHelper(context)
db = dbHelper.writableDatabase
return db != null
}
override fun query(
uri: Uri, projection: Array<String>?, selection: String?,
selectionArgs: Array<String>?, sortOrder: String?
): Cursor? {
var sortOrder = sortOrder
val qb = SQLiteQueryBuilder()
qb.tables = TABLE_NAME
if (uriMatcher!!.match(uri) == uriCode) {
qb.projectionMap = values
} else {
throw IllegalArgumentException("Unknown URI $uri")
}
if (sortOrder == null || sortOrder == "") {
sortOrder = id
}
val c = qb.query(
db, projection, selection, selectionArgs, null,
null, sortOrder
)
c.setNotificationUri(context!!.contentResolver, uri)
return c
}
override fun insert(uri: Uri, values: ContentValues?): Uri {
val rowID = db!!.insert(TABLE_NAME, "", values)
if (rowID > 0) {
val uri1 = ContentUris.withAppendedId(CONTENT_URI, rowID)
context!!.contentResolver.notifyChange(uri1, null)
return uri1
}
throw SQLiteException("Failed to add a record into $uri")
}
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array<String>?
): Int {
val count: Int = if (uriMatcher!!.match(uri) == uriCode) {
db!!.update(TABLE_NAME, values, selection, selectionArgs)
} else {
throw IllegalArgumentException("Unknown URI $uri")
}
context!!.contentResolver.notifyChange(uri, null)
return count
}
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
val count: Int = if (uriMatcher!!.match(uri) == uriCode) {
db!!.delete(TABLE_NAME, selection, selectionArgs)
} else {
throw IllegalArgumentException("Unknown URI $uri")
}
context!!.contentResolver.notifyChange(uri, null)
return count
}
private var db: SQLiteDatabase? = null
private class DatabaseHelper(context: Context?) :
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(CREATE_DB_TABLE)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("DROP TABLE IF EXISTS $TABLE_NAME")
onCreate(db)
}
}
}
Now, in MainActivity.kt, write the following code:
Code
package com.codingninjas.contentprovider
import android.content.ContentValues
import android.net.Uri
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
return true
}
fun onClickAddDetails(view: View?) {
val values = ContentValues()
values.put(
YourProvider.name,
(findViewById<View>(R.id.txtName) as EditText).text.toString()
)
contentResolver.insert(YourProvider.CONTENT_URI, values)
Toast.makeText(baseContext, "New Record Inserted", Toast.LENGTH_LONG).show()
}
fun onClickShowDetails(view: View?) {
val resultView = findViewById<View>(R.id.res) as TextView
val cursor = contentResolver.query(
Uri.parse("content://com.codingninjas.contentprovider.UserProvider/users"),
null,
null,
null,
null
)
if (cursor!!.moveToFirst()) {
val strBuild = StringBuilder()
while (!cursor.isAfterLast) {
strBuild.append(
"""
${cursor.getString(cursor.getColumnIndex("id"))}-
""".trimIndent() + cursor.getString(
cursor.getColumnIndex("name")
)
)
cursor.moveToNext()
}
resultView.text = strBuild
} else {
resultView.text = "No Records Found"
}
}
}
After that, open activity main.xml and write the following code, where we've designed the application's layout:
Code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:text="Coding Ninjas"
android:textColor="#FF5252"
android:textSize="40sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:layout_marginTop="50dp"
android:text="Coding Ninjas User" />
<EditText
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:ems="20" />
<Button
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:onClick="onClickAddDetails"
android:text="Add User" />
<Button
android:id="@+id/btnRetrieve"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:onClick="onClickShowDetails"
android:text="Show Users" />
<TextView
android:id="@+id/res"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:clickable="false"
android:ems="20" />
</LinearLayout>
Write the following code in the AndroidManifest.xml file:
Code
<application>
<provider
android:authorities="com.codingninjas.contentprovider.UserProvider"
android:name="com.codingninjas.contentprovider.YourProvider"
android:exported="false">
</provider>
</application>
Following that, you'll see an application that looks like this:
Output

When we click on Add User, it will store the text we passed to EditText into our database. By Clicking on Show User, we can see the stored data throughout any app.
FAQs
-
Is SQLite a content provider?
A SQLite database built on Android by one program is solely accessible to that application and cannot be accessed by other applications. As a result, if you need to communicate data between applications, you should use the content provider paradigm, as advised by Android.
-
How do I update my content provider on Android?
You can use insert/update query. insert(Uri, ContentValues) adds new data to the content provider. update(Uri, ContentValues, Bundle) changes the content provider's existing data.
-
Is content provider thread-safe?
The ContentProvider lacks thread safety. We will generally find that no additional work is required on your part to prevent dangerous race situations.
Key Takeaways
In this article, we have extensively discussed Content Provider in Android and its example.
You can head over to our Android Development Course on the Coding Ninjas Website to dive deep into Android Development and build future applications.
We hope that this blog has helped you enhance your knowledge regarding content providers, their examples and if you would like to learn more, check out our articles on Sharing App Data in Android. Do upvote our blog to help other ninjas grow. Happy Coding!