Creating the Content Provider class
package com.example.contentprovidersinandroid
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 MyContentProvider : ContentProvider() {
companion object {
// defining authority so that other application can access it
const val PROVIDER_NAME = "com.demo.user.provider"
// defining content URI
const val URL = "content://$PROVIDER_NAME/users"
// parsing the content URI
val CONTENT_URI = Uri.parse(URL)
const val id = "id"
const val name = "name"
const val uriCode = 1
var uriMatcher: UriMatcher? = null
private val values: HashMap<String, String>? = null
// declaring name of the database
const val DATABASE_NAME = "UserDB"
// declaring table name of the database
const val TABLE_NAME = "Users"
// declaring version of the database
const val DATABASE_VERSION = 1
// sql query to create the table
const val CREATE_DB_TABLE =
(" CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " name TEXT NOT NULL);")
init {
// to match the content URI
// every time user access table under content provider
uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
// to access whole table
uriMatcher!!.addURI(
PROVIDER_NAME,
"users",
uriCode
// to access a particular row
// of the table
uriMatcher!!.addURI(
PROVIDER_NAME,
"users/*",
uriCode
)
}
override fun getType(uri: Uri): String? {
return when (uriMatcher!!.match(uri)) {
uriCode -> "vnd.android.cursor.dir/users"
else -> throw IllegalArgumentException("Unsupported URI: $uri")
// creating the database
override fun onCreate(): Boolean {
val context = context
val dbHelper =
DatabaseHelper(context)
db = dbHelper.writableDatabase
return if (db != null) {
true
} else false
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
when (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
// adding data to the database
override fun insert(uri: Uri, values: ContentValues?): Uri? {
val rowID = db!!.insert(TABLE_NAME, "", values)
if (rowID > 0) {
val _uri =
ContentUris.withAppendedId(CONTENT_URI, rowID)
context!!.contentResolver.notifyChange(_uri, null)
return _uri
throw SQLiteException("Failed to add a record into $uri")
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array<String>?
): Int {
var count = 0
count = when (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 {
var count = 0
count = when (uriMatcher!!.match(uri)) {
uriCode -> db!!.delete(TABLE_NAME, selection, selectionArgs)
else -> throw IllegalArgumentException("Unknown URI $uri")
context!!.contentResolver.notifyChange(uri, null)
return count
// creating object of database
// to perform query
private var db: SQLiteDatabase? = null
// creating a database
private class DatabaseHelper // defining a constructor
internal constructor(context: Context?) : SQLiteOpenHelper(
context,
DATABASE_NAME,
null,
DATABASE_VERSION
){
// creating a table in the database
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(CREATE_DB_TABLE)
override fun onUpgrade(
db: SQLiteDatabase,
oldVersion: Int,
newVersion: Int
){
// sql query to drop a table
// having similar name
db.execSQL("DROP TABLE IF EXISTS $TABLE_NAME")
onCreate(db)
Design the activity_main.xml layout
XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#168BC34A"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.13"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginBottom="70dp"
android:fontFamily="@font/roboto"
android:text="@string/heading"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="@android:color/holo_green_dark"
android:textSize="36sp"
android:textStyle="bold" />
<EditText
android:id="@+id/textName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="40dp"
android:fontFamily="@font/roboto"
android:hint="@string/hintText" />
<Button
android:id="@+id/insertButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="#4CAF50"
android:fontFamily="@font/roboto"
android:onClick="onClickAddDetails"
android:text="@string/insertButtontext"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
android:textColor="#FFFFFF"
android:textStyle="bold" />
<Button
android:id="@+id/loadButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="#4CAF50"
android:fontFamily="@font/roboto"
android:onClick="onClickShowDetails"
android:text="@string/loadButtonText"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
android:textColor="#FFFFFF"
android:textStyle="bold" />
<TextView
android:id="@+id/res"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:clickable="false"
android:ems="10"
android:fontFamily="@font/roboto"
android:textColor="@android:color/holo_green_dark"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/banner" />
</androidx.constraintlayout.widget.ConstraintLayout>
Modify the MainActivity file
package com.example.content_provider_in_android
import android.content.ContentValues
import android.content.Context
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
import com.example.contentprovidersinandroid.MyContentProvider
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(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
return true
}
fun onClickAddDetails(view: View?) {
// class to add values in the database
val values = ContentValues()
// fetching text from user
values.put(MyContentProvider.name, (findViewById<View>(R.id.textName) as
EditText).text.toString())
// inserting into database through content URI
contentResolver.insert(MyContentProvider.CONTENT_URI, values)
// displaying a toast message
Toast.makeText(baseContext, "New Record Inserted", Toast.LENGTH_LONG).show()
fun onClickShowDetails(view: View?) {
// inserting complete table details in this text field
val resultView = findViewById<View>(R.id.res) as TextView
// creating a cursor object of the
// content URI
val cursor = contentResolver.query(Uri.parse("content://com.demo.user.provider/users"), null,
null, null, null)
// iteration of the cursor
// to print whole table
if (cursor!!.moveToFirst()) {
val strBuild = StringBuilder()
while (!cursor.isAfterLast) {
strBuild.append("""
${cursor.getString(cursor.getColumnIndex("id"))}-$
{cursor.getString(cursor.getColumnIndex("name"))}
""".trimIndent())
cursor.moveToNext()
resultView.text = strBuild
} else {
resultView.text = "No Records Found"
Modify the AndroidManifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.content_provider_in_android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<provider
android:name="com.example.contentprovidersinandroid.MyContentProvider"
android:authorities="com.demo.user.provider"
android:enabled="true"
android:exported="true"></provider>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application>
</manifest>
Designing the activity_main.xml layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#168BC34A"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.13"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginBottom="70dp"
android:fontFamily="@font/roboto"
android:text="@string/heading"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="@android:color/holo_green_dark"
android:textSize="36sp"
android:textStyle="bold" />
<Button
android:id="@+id/loadButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="#4CAF50"
android:fontFamily="@font/roboto"
android:onClick="onClickShowDetails"
android:text="@string/loadButtonText"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
android:textColor="#FFFFFF"
android:textStyle="bold" />
<TextView
android:id="@+id/res"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:clickable="false"
android:ems="10"
android:fontFamily="@font/roboto"
android:textColor="@android:color/holo_green_dark"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/banner" />
</androidx.constraintlayout.widget.ConstraintLayout>
Modify the MainActivity file
package com.example.accessing_content_provider
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
var CONTENT_URI = Uri.parse("content://com.demo.user.provider/users")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fun onClickShowDetails(view: View?) {
// inserting complete table details in this text field
val resultView = findViewById<View>(R.id.res) as TextView
// creating a cursor object of the
// content URI
val cursor = contentResolver.query(Uri.parse("content://com.demo.user.provider/users"), null,
null, null, null)
// iteration of the cursor
// to print whole table
if (cursor!!.moveToFirst()) {
val strBuild = StringBuilder()
while (!cursor.isAfterLast) {
strBuild.append("""
${cursor.getString(cursor.getColumnIndex("id"))}-$
{cursor.getString(cursor.getColumnIndex("name"))}
""".trimIndent())
cursor.moveToNext()
resultView.text = strBuild
} else {
resultView.text = "No Records Found"
Modify strings.xml file
<resources>
<string name="app_name">Accessing_Content_Provider</string>
<string name="heading">Accessing data of Content Provider</string>
<string name="loadButtonText">Load Data</string>
</resources>
Modify the strings.xml file
<resources>
<string name="app_name">Content_Provider_In_Android</string>
<string name="hintText">Enter User Name</string>
<string name="heading">Content Provider In Android</string>
<string name="insertButtontext">Insert Data</string>
<string name="loadButtonText">Load Data</string>
</resources>
OUTPUT