In Android, a content provider is a component that manages access to a central repository of data. It is a part of Android app architecture that allows the Android apps to share data securely between different apps. The data can be stored in a file system, in an SQLite database, on the web, or in some persistent location. For example: In order to have access to user contacts, third-party mobile apps use the content provider to access the contacts database.
What happens when we allow access to contacts in the mobile app?
In this tutorial, we will implement a content provider with an app that will ask to have access to contacts and will visualize what happens in the backend when we all allow access to our resources (contacts, location, gallery, etc.).
Steps to implement Content Provider in Android
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.
Step 2: Add manifest permission
As we want out app to access the contact application of our mobile phone, we need to add READ_CONTACTS and WRITE_CONTACTS permission for contacts in our manifest file. We will add the following permission to our AndroidManifest.xml file:
<!--Adding READ and WRITE CONTACTS permission-->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
Step 3: Create a layout
We will create a simple layout that has one button to access contacts in the mobile application.
<?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"
tools:context=".MainActivity">
<Button
android:id="@+id/accessBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Access Contacts"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Step 4: Add Callback
Above, we have one button in our user interface; we need to set onClick listener to it in our MainActivity.java file. First, we need to initialize the button and set a callback to it. After this onClick() method, we are invoking a method call that will use ContentResolver to have access to the contacts database, and then, with the help of the Cursor object, we traverse the result of our query and log the contact details.
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* Initializing button and adding callback to it.
* @author: paulsofts
*/
Button btn = findViewById(R.id.accessBtn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getContacts();
}
});
}
public void getContacts(){
// Check if the permission to read contacts has been granted
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED){
// If permission is not granted, request it from the user
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 0);
}
// Obtain the ContentResolver, which provides access to the database of contacts
ContentResolver resolver = getContentResolver();
// Define the URI to access the phone contacts
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
// Query the contacts database using the resolver to get a cursor for contact data
Cursor cursor = resolver.query(uri, null, null, null, null);
// Check if there are any contacts in the cursor and loop through each contact in the cursor
if(cursor.getCount() > 0){
while (cursor.moveToNext()) {
@SuppressLint("Range") String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
@SuppressLint("Range") String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i("Contact Permission", "Name: " + name + " " + "Ph: " + number);
}
}
}
}
Step 5: Test application
Now, we will run and test our application.