ContentProvider mechanism
The Android system sets the read-write permission for the data file of the application. In order to realize the function of accessing data across applications, Android provides the ContentProvider mechanism. ContentProvider is one of the four components of Android. It is used to share data externally and realize cross application data sharing. The ContentProvider application component combines the file permission mechanism to protect and open its own data to other applications.
Functions of ContentProvider
- Accessing system resources: developers can access the data provided by the system by using ContentProvider, such as address book, audio, video, pictures, etc., which is equivalent to an intermediary. The real data source is files or SQLite.
- Sharing custom resources: developers can write custom ContentProviders in applications and provide their own data to other applications. They can also add data to an existing ContentProvider after obtaining write permission.
data model
The ContentProvider provides the stored data to the visitor in the form of a data table. Each row in the data table is a record, and each column is data with specific type and meaning. Each data record includes an "ID" value field, which uniquely identifies a piece of data. The data structure returned by the ContentProvider is the Cursor object, that is, the result set, which is similar to the ResultSet in JDBC.
URL
Composition of URL
Universal resource identifier (URI) represents the data to be operated. Each resource of Android (such as image, video, etc.) can be represented by URI. Each Content Provider provides a public URI that can uniquely identify its own data set. If a data source contains multiple contents (such as multiple tables), it needs to be distinguished with different URIs.
The URI consists of three parts: the naming mechanism (schema) for accessing the resource, the host name for storing the resource and the name of the resource itself. For example:
content://com.example.provider.NoteProvider/notes/3
component | character string | explain |
---|---|---|
Naming mechanism for accessing resources | content:// | Represents data controlled by the ContentProvider |
Host name where the resource is stored | com.example.provider.NoteProvider | Unique identifier used to locate the ContentProvider |
The name of the resource itself | /notes/3 | The internal path part of each ContentProvider points to a collection of objects, usually the name of the table |
For example, ": / Notes" indicates a collection of notes, which returns all records in the table. If there is a path in the future, it points to a specific record, such as the note with id 3 shown in ": / notes/3 table.
Create URL
The URL is created using URI Parse() method, just give the string directly. For example:
Uri uri = Uri.parse("content://com.example.mycontact /people");
Action URL
The Android system provides two tool classes for manipulating URI s, UriMatcher and ContentUris.
UriMatcher class
The UriMatcher class is used to extract the data table for the next data operation. Compared with manually filtering strings, using UriMatcher is not only simple, but also maintainable.
The construction method of initializing the UriMatcher class is as follows, where the parameter matching code is an integer greater than zero (representing the matching root path), or the constant UriMatcher NO_ Match (integer - 1, indicating mismatched root path).
UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
Register the required URI and add other URI matching paths as follows. The first parameter is the AUTHORITY string, the second parameter is the path to be matched, and the third parameter must be a matching code greater than zero.
URI_MATCHER.addURI(AUTHORITY, TABLE_A, TABLE_A_MSG);
ContentUris class
The ContentUris class is used to obtain the ID part behind the URI path and add the ID to the URI through the withappendedd() method:
Uri resultUri = ContentUris.withAppendedId(uri, 10);
You can also get the ID from the path through parseId(uri), for example:
Uri uri = Uri.parse("content://com.example.mycontact/people/10") long personid = ContentUris.parseId(uri);
ContentProvider
The ContentProvider class implements a set of standard method interfaces through which other applications can operate the internal data of the application. The main methods of ContentProvider are as follows:
public boolean onCreate(); //Called when creating a ContentProvider public Cursor query(Uri,String[], String, String[], String); //Query the ContentProvider of the specified Uri and return a Cursor public Uri insert(Uri,Content Values); //Add data to the ContentProvider of the specified Uri public int update(Uri,ContentValues,String,String[]); //Updates the data in the ContentProvider of the specified Uri public int delete(Uri,String,String[]); //Deletes data from the ContentProvider of the specified Uri public String getType(Uri); //Returns the MIME type of the data in the specified Uri
Most Content Provider s define contract classes to contain the MIME types they use, such as the contract class contactscontract Rawcontacts defines the constant CONTENT_ITEM_TYPE, which corresponds to a row of original contact data.
URI | explain |
---|---|
ContactsContract.Contacts.CONTENT_URI | Administrative Contact |
ContactsContract.CommonDataKinds.Phone.CONTENT_URI | Manage contact's phone |
ContactsContract.CommonDataKinds.Email.CONTENT_URI | Manage email for contacts |
ContactsContract.Contacts.DISPLAY NAME | Names displayed in contacts |
ContactsContract.Contacts.HAS_PHONE_NUMBER | Is there a phone in the contact |
ContactsContract.Data.CONTACT_ID | ID displayed in contact |
ContactsContract.CommonDataKinds.Phone.NUMBER | Phone number displayed in contact |
ContactsContract.CommonDataKinds.Phone.TYPE | The type of phone number displayed in the contact (office, home, etc.) |
ContactsContract.CommonDataKinds.Email.DATA | Email displayed in contacts |
ContactsContract.CommonDataKinds.Email.TYPE | The type of email displayed in the contact (individual, organization, etc.) |
ContentResolver
The working principle of ContentProvider is single instance mode. The system has only one instance of ContentProvider, and the users of ContentProvider cannot access it directly. To access this instance, you must operate the ContentProvider through ContentResolver so that it can communicate with ContentResolver objects in multiple programs and processes.
In order to realize the operation of data, the interface provided by ContentResolver corresponds to the interface provided by ContentProvider one by one, mainly including the following methods.
The method is getContentResolver();:
ContentResolver cr = getContentResolver(); //Get an instance of ContentResolver query(Uri uri,String[] projection, String selection,String[] selectionArgs, String sortOrder) //Query through Uri and return a Cursor insert(Uri uri,Content Values values); //Inserts a set of data into the location specified by Uri. update(Uri uri,ContentValues values,String where,Stringll selectionArgs); //Update the data at the location specified by Uri. delete(Uri uri,String where,String[] selectionArgs); //Delete the data with the specified Uri and meeting certain conditions.
ContentProvider sample
Program requirements
Enter the phone number to dial and query the name according to the phone number. If this number is in the address book, the name of the phone owner will be displayed; otherwise, the words "stranger" will be displayed.
Code writing
activity_main
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" android:gravity="center" android:text="Outgoing call:" /> <EditText android:id="@+id/editText1" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="11" > </EditText> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="dial" /> <TextView android:id="@+id/textView2" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:textSize="20dp" android:text="" /> </LinearLayout> </LinearLayout>
MainActivity
When a user enters a phone number, he first needs to use a regular expression to determine whether the phone number is legal. If it is legal, get the contact information through the ContentProvider, and find out whether there is the name of the contact through the returned Cursor object. If yes, the contact will be displayed. If not, the stranger will be displayed. Finally, use the intent mechanism to make a call.
package com.example.liaison; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.content.ContentResolver; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract.Data; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; public class MainActivity extends AppCompatActivity { private EditText editText1; private TextView textView2; private Button button1; String phoneNumber = ""; String displayName = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText1 = (EditText) findViewById(R.id.editText1); textView2 = (TextView) findViewById(R.id.textView2); button1 = (Button) findViewById(R.id.button1); button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { phoneNumber = editText1.getText().toString(); // The phone number entered is legal if (isPhoneLegal(phoneNumber)) { // Find contacts by phone number Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + phoneNumber); ContentResolver resolver = getContentResolver(); Cursor cursor = resolver.query(uri, new String[] {Data.DISPLAY_NAME}, null, null, null); // Determine whether the number is in the address book if (cursor.moveToFirst()) { textView2.setText("You will call:" + cursor.getString(0)); // Display name } else { textView2.setText("You will call: stranger"); } // Making calls using intent Intent intent = new Intent(); intent.setAction(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:" + phoneNumber)); startActivity(intent); } // The phone number entered is legal else{ textView2.setText("Please enter the correct phone number!"); } } }); } // judge public static boolean isPhoneLegal(String str) throws PatternSyntaxException { String regExp = "^((13[0-9])|(14[5,7,9])|(15[0-3,5-9])|(166)|(17[3,5,6,7,8])|(18[0-9])|(19[8,9]))\\d{8}$"; Pattern p = Pattern.compile(regExp); Matcher m = p.matcher(str); return m.matches(); } }
Apply for permission
You need to apply for permission to read contacts and call:
<uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.CALL_PHONE"/>
Operation effect
First, add test data to contacts:
Phone number in contact:
Phone not in contact list:
Illegal string entered:
reference material
Android mobile application development, edited by Yang Yi and Deputy edited by Yu dekuang, people's Posts and Telecommunications Press