Content Provider

Content Providers in Android are one of the fundamental components that allow apps to share data securely with other apps. They act as an interface to access and manage structured data stored in an app and can provide data from SQLite databases, files, or even remote data sources.

What is a Content Provider?

A Content Provider is a component in Android that enables an application to store, retrieve, and share data with other applications using a standardized interface. It encapsulates data and enforces security while providing a uniform API for data access.

📌 Key Points:
✔ Used to access data from databases (SQLite), files, or the cloud
✔ Uses a URI (Uniform Resource Identifier) for identifying data
✔ Allows CRUD (Create, Read, Update, Delete) operations
✔ Provides inter-app communication for data sharing

When to Use a Content Provider?

Use a Content Provider when:
Sharing data between apps (e.g., sharing contacts, files)
Managing structured data stored in SQLite or another data source
Providing data to UI elements via CursorLoader
Accessing data asynchronously

❌ When NOT to use:

  • If data is private to the app and no external access is needed.
  • If SharedPreferences or a simple file is sufficient.

How to Use a Content Provider?

There are two main ways to work with Content Providers:

  1. Using an existing Content Provider (e.g., Contacts, MediaStore)
  2. Creating your own Content Provider (for sharing custom data)

Using an Existing Content Provider (Example: Reading Contacts)

Android provides built-in Content Providers like:

  • ContactsContract (to access contacts)
  • MediaStore (to access media files)
  • CallLog (to access call history)

This Android app reads contacts from the phone’s contact list and displays them in a TextView. However, before accessing the contacts, it checks if the READ_CONTACTS permission is granted. If not, it requests permission from the user.

First, in the AndroidManifest.xml file add the following code just before the application tag to permit to access the contacts

<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>

onCreate() – Checking and Requesting Permission

📌 What happens here?

  • When the app starts (onCreate() method), it first sets up the layout (activity_main.xml).
  • Then, it tries to access the phone’s contacts.
  • If the READ_CONTACTS permission is not granted, the app requests permission from the user.
  • If the permission is already granted, it directly calls fetchContacts().

📌 Key Code in onCreate():

If permission is granted, it fetches the contacts.
If permission is denied, it asks the user for permission.

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        contactsTextView = findViewById(R.id.textView);

        // Check and request permission
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_READ_CONTACTS);
        } else {
            fetchContacts();  // If permission is already granted
        }
    }

onRequestPermissionsResult( ) – Handling Permission Response

📌 What happens here?

  • If the user grants permission, the app calls fetchContacts() to display contacts.
  • If the user denies permission, it shows a message: "Permission denied!".

📌 Key Code:

If permission is granted, contacts are fetched.
If permission is denied, a toast message is shown.

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_READ_CONTACTS) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                fetchContacts();
            } else {
                Toast.makeText(this, "Permission denied!", Toast.LENGTH_SHORT).show();
            }
        }
    }

fetchContacts( ) – Getting Contacts and Displaying Them

📌 What happens here?

  • This method fetches contacts’ names and phone numbers from the phone’s contact list.
  • It uses ContentResolver to query the ContactsContract (a built-in Android database for storing contacts).
  • The contacts are stored in a StringBuilder and displayed in the TextView.

📌 Key Code:

✅ It retrieves the name and phone number of each contact.
✅ It appends them to a StringBuilder.
✅ The result is displayed in a TextView.

private void fetchContacts() {
        StringBuilder contacts = new StringBuilder();
        Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);

        if (cursor != null && cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                String phoneNumber = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
                contacts.append(name).append(": ").append(phoneNumber).append("\n");
            }
            cursor.close();
        } else {
            contacts.append("No contacts found.");
        }

        // Display contacts in TextView
        contactsTextView.setText(contacts.toString());
    }

Complete java code

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_READ_CONTACTS = 1;
    private TextView contactsTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        contactsTextView = findViewById(R.id.textView);

        // Check and request permission
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_READ_CONTACTS);
        } else {
            fetchContacts();  // If permission is already granted
        }
    }

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_READ_CONTACTS) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                fetchContacts();
            } else {
                Toast.makeText(this, "Permission denied!", Toast.LENGTH_SHORT).show();
            }
        }
    }

    // Fetch Contacts from PhoneBook
    private void fetchContacts() {
        StringBuilder contacts = new StringBuilder();
        Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);

        if (cursor != null && cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                String phoneNumber = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
                contacts.append(name).append(": ").append(phoneNumber).append("\n");
            }
            cursor.close();
        } else {
            contacts.append("No contacts found.");
        }

        // Display contacts in TextView
        contactsTextView.setText(contacts.toString());
    }
}