Android: ContentProvider data access

Posted by freakstyle on Thu, 03 Feb 2022 06:48:19 +0100

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

  1. 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.
  2. 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

Topics: Android