Android Content provider component

Content Provider is one of the components of Android applications. As the only way to share data between applications, the main function of Content Provider is to store and retrieve data and provide excuses for other applications to access data.

The Android system has built-in a series of content providers for some common data types (such as music, video, image, mobile phone address book, contact information, etc.), which are located under the android.provider package. With a specific license, you can access these content providers in your own applications.

There are two ways to share your own data with other applications: create your own Content Provider (that is, a subclass inherited from ContentProvider) or add your own data to the existing Content Provider. The latter needs to ensure that the existing Content Provider has the same data type as your own and has the write permission of the Content Provider. For the Content Provider, the most important are the data model and URI.

1. Data model The Content Provider provides its stored data to visitors in the form of data table. In the data table, each row is a record, and each column is data with specific type and meaning. Each data record includes a "_ID" value field, which uniquely identifies a piece of data.

2.URI URI, each Content Provider provides a public URI that can uniquely identify its own data set. If a Content Provider manages multiple data sets, it will assign an independent URI to each data set. The URIs of all content providers begin with "content: / /", where "content:" is the schema used to identify that the data is managed by the Content Provider.

URIs are used in almost all Content Provider operations. Therefore, generally speaking, if it is a self-developed Content Provider, it is best to define the URI as a constant, which not only simplifies the development, but also improves the maintainability of the code.

First, let's introduce how to access the data in the Content Provider. The data in the Content Provider is accessed mainly through the ContentResolver object. The ContentResolver class provides member methods, which can be used to query, insert, modify and delete the data in the Content Provider. Taking query as an example, querying a Content Provider requires the following information.

URI that uniquely identifies the Content Provider Name of the data field to access. The data type of the data field

Tip: if you need to access a specific data record, you only need the ID of the record.

There are two methods to query the Content Provider: query() of ContentResolver and managedQuery() of Activity object. Both receive the same parameters and return the Cursor object. The only difference is that the managedQuery method allows the Activity to manage the Cursor life cycle.

The managed Cursor will call its own deactivate method to unload itself when the Activity enters the suspended state, and call its own requery method to re query the generated Cursor object when the Activity returns to the running state. If an unmanaged Cursor object wants to be managed by the Activity, it can be implemented by calling the startManagingCursor method of the Activity.

Android applications can use files or SqlLite databases to store data. The Content Provider provides a way to share data among multiple applications. For example, contact information can be accessed by multiple applications. Content Provider is a class that implements a set of standard methods for providing access to data by other applications.

Applications can perform the following operations in the Content Provider: Query data

Modify data

Add data

Delete data

/Chapter10_ContentProvider_01_Test02/src/com/amaker/ch10/app/MainActivity.java

package com.amaker.ch10.app;  
 
import android.app.Activity;  
import android.content.ContentUris;  
import android.content.ContentValues;  
import android.database.Cursor;  
import android.net.Uri;  
import android.os.Bundle;  
import android.util.Log;  
 
import com.amaker.ch10.app.Employees.Employee;  
 
public class MainActivity extends Activity {  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        // add to  
        insert();  
        // query  
        query();  
        // to update  
        update();  
        // query  
        query();  
        // delete  
        del();  
        // query  
        query();  
    }  
    // Delete method  
    private void del(){  
        // Delete record with ID 1  
        Uri uri = ContentUris.withAppendedId(Employee.CONTENT_URI, 1);  
        // Get the ContentResolver and delete it  
        getContentResolver().delete(uri, null, null);  
    }  
    // to update  
    private void update(){  
        // Update record with ID 1  
        Uri uri = ContentUris.withAppendedId(Employee.CONTENT_URI, 1);  
        ContentValues values = new ContentValues();  
        // Add employee information  
        values.put(Employee.NAME, "hz.guo");  
        values.put(Employee.GENDER, "male");  
        values.put(Employee.AGE,31);  
        // Get ContentResolver and update  
        getContentResolver().update(uri, values, null, null);  
    }  
    // query  
    private void query(){  
        // Query column array  
           String[] PROJECTION = new String[] {   
                   Employee._ID,         // 0  
                   Employee.NAME,         // 1  
                   Employee.GENDER,     // 2  
                   Employee.AGE         // 3  
        };  
        // Query all memo information  
        Cursor c = managedQuery(Employee.CONTENT_URI, PROJECTION, null,  
                null, Employee.DEFAULT_SORT_ORDER);  
        // Determine whether the cursor is empty  
        if (c.moveToFirst()) {  
            // Traversal cursor  
            for (int i = 0; i < c.getCount(); i++) {  
                c.moveToPosition(i);  
                // Get name  
                String name = c.getString(1);  
                String gender = c.getString(2);  
                int age = c.getInt(3);  
                // Output log  
                Log.i("emp", name+":"+gender+":"+age);  
            }  
        }  
    }  
    // insert  
    private void insert(){  
        // Declaration Uri  
        Uri uri = Employee.CONTENT_URI;  
        // Instantiate ContentValues  
        ContentValues values = new ContentValues();  
        // Add employee information  
        values.put(Employee.NAME, "amaker");  
        values.put(Employee.GENDER, "male");  
        values.put(Employee.AGE,30);  
        // Get ContentResolver and insert  
        getContentResolver().insert(uri, values);  
    }  
} 

/Chapter10_ContentProvider_01_Test02/src/com/amaker/ch10/app/Employees.java

package com.amaker.ch10.app;  
 
import android.net.Uri;  
import android.provider.BaseColumns;  
 
/**  
 * Address book constant class  
 */  
public final class Employees {  
    // Authorization constant  
    public static final String AUTHORITY = "com.amaker.provider.Employees";  
    private Employees() {}  
    // Inner class  
    public static final class Employee implements BaseColumns {  
        // Construction method  
        private Employee() {}  
        // Access Uri  
        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/employee");  
        // Content type  
        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.amaker.employees";  
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.amaker.employees";  
          
        // Default sort constant  
        public static final String DEFAULT_SORT_ORDER = "name DESC";// Sort by name  
        // Table field constant  
        public static final String NAME = "name";                    // full name  
        public static final String GENDER= "gender";                // Gender  
        public static final String AGE = "age";                     // Age  
    }  
} 

/Chapter10_ContentProvider_01_Test02/src/com/amaker/ch10/app/EmployeeProvider.java

package com.amaker.ch10.app;  
 
import java.util.HashMap;  
 
import android.content.ContentProvider;  
import android.content.ContentUris;  
import android.content.ContentValues;  
import android.content.UriMatcher;  
import android.database.Cursor;  
import android.database.sqlite.SQLiteDatabase;  
import android.database.sqlite.SQLiteQueryBuilder;  
import android.net.Uri;  
import android.text.TextUtils;  
 
import com.amaker.ch10.app.Employees.Employee;  
 
public class EmployeeProvider extends ContentProvider{  
    // Database help class  
    private DBHelper dbHelper;  
    // Uri tool class  
    private static final UriMatcher sUriMatcher;  
    // Query and update conditions  
    private static final int EMPLOYEE = 1;  
    private static final int EMPLOYEE_ID = 2;  
    // Query column set  
    private static HashMap<String, String> empProjectionMap;  
    static {  
        // Uri matching tool class  
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);  
        sUriMatcher.addURI(Employees.AUTHORITY, "employee", EMPLOYEE);  
        sUriMatcher.addURI(Employees.AUTHORITY, "employee/#", EMPLOYEE_ID);  
        // Instantiate query column collection  
        empProjectionMap = new HashMap<String, String>();  
        // Add query column  
        empProjectionMap.put(Employee._ID, Employee._ID);  
        empProjectionMap.put(Employee.NAME, Employee.NAME);  
        empProjectionMap.put(Employee.GENDER, Employee.GENDER);  
        empProjectionMap.put(Employee.AGE, Employee.AGE);  
    }  
 
    // Create is call  
    public boolean onCreate() {  
        // Instantiate database help class  
        dbHelper = new DBHelper(getContext());  
        return true;  
    }  
    // Add method  
    public Uri insert(Uri uri, ContentValues values) {  
        // Get database instance  
        SQLiteDatabase db = dbHelper.getWritableDatabase();  
        // Insert data and return row ID  
        long rowId = db.insert(DBHelper.EMPLOYEES_TABLE_NAME, Employee.NAME, values);  
        // If the insertion is successful, the uri is returned  
        if (rowId > 0) {  
            Uri empUri = ContentUris.withAppendedId(Employee.CONTENT_URI, rowId);  
            getContext().getContentResolver().notifyChange(empUri, null);  
            return empUri;  
        }  
        return null;  
    }  
    // Delete method  
    public int delete(Uri uri, String selection, String[] selectionArgs) {  
        // Get database instance  
        SQLiteDatabase db = dbHelper.getWritableDatabase();  
         // Get database instance  
        int count;  
        switch (sUriMatcher.match(uri)) {  
        // Delete according to specified conditions  
        case EMPLOYEE:  
            count = db.delete(DBHelper.EMPLOYEES_TABLE_NAME, selection, selectionArgs);  
            break;  
        // Delete according to the specified condition and ID  
        case EMPLOYEE_ID:  
            String noteId = uri.getPathSegments().get(1);  
            count = db.delete(DBHelper.EMPLOYEES_TABLE_NAME, Employee._ID + "=" + noteId  
                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);  
            break;  
 
        default:  
            throw new IllegalArgumentException("FALSE URI " + uri);  
        }  
        getContext().getContentResolver().notifyChange(uri, null);  
        return count;  
    }  
 
    // Get type  
    public String getType(Uri uri) {  
        return null;  
    }  
 
    // Query method  
    public Cursor query(Uri uri, String[] projection, String selection,  
            String[] selectionArgs, String sortOrder) {  
         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();  
            switch (sUriMatcher.match(uri)) {  
            // Query all  
            case EMPLOYEE:  
                qb.setTables(DBHelper.EMPLOYEES_TABLE_NAME);  
                qb.setProjectionMap(empProjectionMap);  
                break;  
            // Query by ID  
            case EMPLOYEE_ID:  
                qb.setTables(DBHelper.EMPLOYEES_TABLE_NAME);  
                qb.setProjectionMap(empProjectionMap);  
                qb.appendWhere(Employee._ID + "=" + uri.getPathSegments().get(1));  
                break;  
            default:  
                throw new IllegalArgumentException("Uri Wrong! " + uri);  
            }  
 
            // Use default sort  
            String orderBy;  
            if (TextUtils.isEmpty(sortOrder)) {  
                orderBy = Employee.DEFAULT_SORT_ORDER;  
            } else {  
                orderBy = sortOrder;  
            }  
 
            // Get database instance  
            SQLiteDatabase db = dbHelper.getReadableDatabase();  
            // Returns a collection of cursors  
            Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);  
            c.setNotificationUri(getContext().getContentResolver(), uri);  
            return c;  
    }  
 
    // Update method  
    public int update(Uri uri, ContentValues values, String selection,  
            String[] selectionArgs) {  
        // Get database instance  
        SQLiteDatabase db = dbHelper.getWritableDatabase();  
        int count;  
        switch (sUriMatcher.match(uri)) {  
        // Update according to specified conditions  
        case EMPLOYEE:  
            count = db.update(DBHelper.EMPLOYEES_TABLE_NAME, values, selection, selectionArgs);  
            break;  
        // Update based on specified criteria and ID  
        case EMPLOYEE_ID:  
            String noteId = uri.getPathSegments().get(1);  
            count = db.update(DBHelper.EMPLOYEES_TABLE_NAME, values, Employee._ID + "=" + noteId  
                    + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs);  
            break;  
        default:  
            throw new IllegalArgumentException("FALSE URI " + uri);  
        }  
        getContext().getContentResolver().notifyChange(uri, null);  
        return count;  
    }  
 
} 

/Chapter10_ContentProvider_01_Test02/src/com/amaker/ch10/app/DBHelper.java

package com.amaker.ch10.app;  
 
import android.content.Context;  
import android.database.sqlite.SQLiteDatabase;  
import android.database.sqlite.SQLiteOpenHelper;  
import com.amaker.ch10.app.Employees.Employee;  
/**  
 *   
 * Database tool class  
 */  
public class DBHelper extends SQLiteOpenHelper{  
    // Database name constant  
    private static final String DATABASE_NAME = "Employees.db";  
    // Database version constant  
    private static final int DATABASE_VERSION = 1;  
    // Table name constant  
    public static final String EMPLOYEES_TABLE_NAME = "employee";  
    // Construction method  
    public DBHelper(Context context) {  
        // Create database  
        super(context, DATABASE_NAME,null, DATABASE_VERSION);  
    }  
 
    // Called on Creation  
    public void onCreate(SQLiteDatabase db) {  
        db.execSQL("CREATE TABLE " + EMPLOYEES_TABLE_NAME + " ("  
                + Employee._ID + " INTEGER PRIMARY KEY,"  
                + Employee.NAME + " TEXT,"  
                + Employee.GENDER + " TEXT,"  
                + Employee.AGE + " INTEGER"  
                + ");");  
    }  
 
    // Called on version update  
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
        // Delete table  
        db.execSQL("DROP TABLE IF EXISTS employee");  
        onCreate(db);  
    }  
 
} 

/Chapter10_ContentProvider_01_Test02/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
      package="com.amaker.ch10.app" 
      android:versionCode="1" 
      android:versionName="1.0"> 
    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
      
        <provider android:name="EmployeeProvider"   
        android:authorities="com.amaker.provider.Employees"/> 
      
        <activity android:name=".MainActivity" 
                  android:label="@string/app_name"> 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
 
    </application> 
    <uses-sdk android:minSdkVersion="3" /> 
 
</manifest>

Posted on Wed, 01 Dec 2021 03:16:22 -0500 by eagle1771