In the Android operating system, each app is hosted in a separate process. Each process might have its own data, that is an app can have its own database. There could be a scenario where another app wants to connect to the first app’s database; this is not possible because the database or the data that is being maintained by the first app is private to that particular app. The only legal mechanism is for the second app to request the data from the first app, and the first app responds back with the data. Now the obvious question is how to make sure that the first app exposes its data in a secure manner. This is where a component content provider comes into the picture. The second app will use an API called ContentResolver which will hit the first app’s database or data and the content provider that is defined in the first app will respond back using a format called the cursor. The content provider abstracts the way in which this inter-communication happens between two apps.
The content resolver provides access to your content provider. As the name suggests, a content resolver accepts requests from clients and resolves them by directing them to a content provider with a distinct authority. The mapping from authorities to content providers is stored by the content resolver. This design is a necessity for simple and secure means of accessing the content providers of other applications. For different abstract methods like insert, query, update, and delete, content resolver uses CRUD (create, read, update, delete) methods.
Inside your activity or adapter class you have to create an object of ContentResolver, which in turn is going to call ContentProvider.
ContentProvider will be providing SQLite databases.SQLite databases inside ContentProvider. The ContentResolver accepts requests from clients.
ContentResolver returns your data as a cursor.
Using data in Activity or Adapter.
ContentProvider provides you with a way to share data with other apps.
SearchRecentSuggestionsProvider: Returns custom search suggestions for apps through the search framework.
AbstractThreadedSyncAdapter: Implements this synchronizing app data with your server.
CursorLoader: Loads data in UI.
Content providers use different methods to store data, such as databases, files, or networks. They provide a way to centralize data in a single place which can be accessed by many different apps. These data are mostly stored in the SQLite database.
Some of the reasons are as follows:
SQLite database represents data in a table.
SQLite database supports the same operations as the content provider.
SQLite database returns requested data as a cursor.
SQLite database provides the same methods and it is easy to work around with SQLite database class.
We have different methods in content provider just like those in a database:
insert(): To insert new data you will call the insert() method of the content provider.
update(): This method updates existing data from the content provider.
delete(): To delete data you will call the delete() method into the content provider. The delete() method deletes existing data from the content provider.
query(): Query method receives a request from the client. The result is returned as a cursor object.
getType(): This method returns the MIME types of the data at the given URI.
Example:
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/btnFetch" android:layout_marginRight="@dimen/tendp" android:layout_marginLeft="@dimen/tendp" android:layout_marginTop="@dimen/fifteendp" android:text="@string/fetch_contacts"/> <ListView android:id="@+id/listContacts" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/twelvedp" android:layout_marginBottom="@dimen/tendp" android:divider="@color/cardview_dark_background" android:dividerHeight="@dimen/onedp" android:listSelector="@color/cardview_light_background" android:smoothScrollbar="true"> </ListView> </LinearLayout>
activity_list_item.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:orientation="horizontal" android:padding="16dp"> <ImageView android:layout_width="@dimen/seventyfivedp" android:layout_height="@dimen/seventyfivedp" android:id="@+id/ivIcon" android:src="@mipmap/ic_launcher" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/tvName" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/nameText" android:textColor="@color/textcolor" android:textStyle="bold" android:layout_margin="@dimen/fivedp" android:textSize="@dimen/twentysp"/> <TextView android:id="@+id/tvNumber" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/numberText" android:textColor="@color/textcolor" android:textStyle="bold" android:layout_margin="@dimen/fivedp" android:textSize="@dimen/fifteensp" /> </LinearLayout> </LinearLayout>
MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.example.contentprovider;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.Activity;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
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.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Button btnFetch;
ListView listContacts;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnFetch = (Button) findViewById(R.id.btnFetch);
listContacts = (ListView) findViewById(R.id.listContacts);
btnFetch.setOnClickListener(v - > {
getPhoneContacts();
});
}
private void getPhoneContacts() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.READ_CONTACTS
}, 0);
}
ContentResolver contentResolver = getContentResolver();
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
Cursor cursor = contentResolver.query(uri, null, null, null, null);
Log.i("CONTACT_PROVIDER", "Total Contacts " + Integer.toString(cursor.getCount()));
String[] contactsName = new String[cursor.getCount()];
String[] contactsNumber = new String[cursor.getCount()];
if (cursor.getCount() > 0) {
int i = 0, j = 0;
while (cursor.moveToNext()) {
String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String contactNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i("CONTACT_PROVIDER", "Contacts Name " + contactName + " Ph: " + contactNumber);
contactsName[i++] = contactName;
contactsNumber[j++] = contactNumber;
}
myAdapter adapter = new myAdapter(this, contactsName, contactsNumber);
listContacts.setAdapter(adapter);
}
}
class myAdapter extends ArrayAdapter < String > {
Context context;
String sName[];
String sNumber[];
myAdapter(Context c, String name[], String number[]) {
super(c, R.layout.activity_list_item, R.id.tvName, name);
this.context = c;
this.sName = name;
this.sNumber = number;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup viewgroup) {
LayoutInflater layoutInflater = (LayoutInflater) getApplicationContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View listItem = layoutInflater.inflate(R.layout.activity_list_item, viewgroup, false);
TextView contactName = listItem.findViewById(R.id.tvName);
TextView contactNumber = listItem.findViewById(R.id.tvNumber);
contactName.setText(sName[position]);
contactNumber.setText(sNumber[position]);
return listItem;
}
}
}
Output