Getting started with Android (13) content provider

Original link: http://www.orlion.ga/612/

Content provider is mainly used to realize the function of data sharing between different applications. It provides a complete mechanism to allow one program to access the data in another program and ensure the security of the accessed data. At present, using content providers is the standard way for Android to share data across programs. Content providers are generally used in two ways. One is to use existing content providers to read and operate the data in the corresponding program, and the other is to create their own content providers to provide external access interfaces to the data of our program.

1、 Accessing data in other programs

Android's own phonebook, SMS, media library and other programs provide external access interfaces, and third-party programs can use these data for development

1. Basic usage of contentresolver

If you want to access the data of the content provider and need to use the contentresolver class, you can get the instance of this class through the getcontentresolver () method in the context. Contentresolver provides many methods for CRUD operations on data, namely insert() \ update() \ delete() \ query(), which is similar to sqlitedatabase, but with different parameters. Crud methods in contentresolver do not accept table names, but use URI parameter instead, which is called content URI. The content URI establishes a unique identifier for the data in the content provider. It is mainly composed of two parts, authority and path. Permissions are used to distinguish different applications. Generally, in order to avoid conflicts, they are named by package name. For example, if the package name of a program is com.example.app, the corresponding permission of the program can be named com.example.app.provider. Paths are used to distinguish between different tables in the same application, and are usually added after permissions. For example, there are two tables in the database of a program, table1 and table2. In this case, the paths can be named / table1 and / table2 respectively, and then the permissions and paths are combined. The content URI becomes com.example.app.provider/table1 and com.example.app.provider/table2. However, it is still difficult to recognize that these two strings are two content URIs. We also need to add a protocol declaration at the head of the string. Therefore, the most standard format of content URI is as follows:

content://com.example.app.provider/table1
content://com.example.app.provider/table2

After getting the content URI string, we need to parse it into a URI object before it can be passed in as a parameter. The parsing method is also quite simple. The code is as follows:

Uri uri = Uri.parse("content://com.example.app.provider/table1")

Now we can use this URI object to query the data in table1 table. The code is as follows:

Cursor cursor = getContentResolver().query(
        uri,        projection,        selection,        selectionArgs,        sortOrder);

After the query is completed, a cursor object is still returned.

Add data operation:

ContentValues values = new ContentValues();
values.put("column1", "text");
values.put("column2", 1);
getContentResolver().insert(uri, values);

Update data operation:

ContentValues values = new ContentValues();
values.put("column1", "");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new
String[] {"text", "1"});

Delete data operation:

getContentResolver().delete(uri, "column2 = ?", new String[] { "1" });

2、 Create your own content provider

1. To create a content provider

You can create your own content provider by creating a new class to inherit the ContentProvider. There are six abstract methods in the ContentProvider class. When we use subclasses to inherit it, we need to override all six methods. The new myprovider inherits from the ContentProvider, and the code is as follows:

package ga.orlion.contactdemo;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;

public class MyProvider extends ContentProvider {

	@Override
	public boolean onCreate() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int delete(Uri uri, String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int update(Uri uri, ContentValues values, String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}

}

Almost every method carries the URI parameter, which is passed when calling the addition, deletion, modification and query method of contentresolver. Now, we need to parse the incoming URI parameters to analyze the tables and data that the caller expects to access.

A standard content URI is written as follows: content://com.example.app.provider/table1 。 This means that the caller expects to access the data in the table1 table of com.example.app. In addition, we can add an ID after the content URI, as shown below:

content://com.example.app.provider/table1/1 。 This means that the caller expects to access the data with ID 1 in the table1 table of com.example.app.

The content URI has only the above two formats. Ending with a path means that you want to access all the data in the table, and ending with an ID means that you want to access the data with the corresponding ID in the table. We can use wildcards to match the content URIs of these two formats respectively. The rules are as follows:

Therefore, a content URI format that can match any table can be written as: content://com.example.app.provider/ *。 A content URI that can match any row of data in the table1 table can be written as: content://com.example.app.provider/table1/# 。

Then, we can easily realize the function of matching content URI with the help of urimatcher. An adduri () method is provided in urimatcher. This method receives three parameters and can pass in permission, path and a user-defined code respectively. In this way, when the match () method of urimatcher is called, a URI object can be passed in, and the return value is a user-defined code that can match the corresponding URI object. Using this code, we can judge which table data the caller expects to access. Modify the code in myprovider as follows:

package com.example.contactdemo;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;

public class MyProvider extends ContentProvider {

	public static final int TABLE1_DIR = 0;
	
	public static final int TABLE1_ITEM = 1;
	
	public static final int TABLE2_DIR = 2;
	
	public static final int TABLE2_ITEM = 3;
	
	private static UriMatcher uriMatcher;
	
	static {
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);
		uriMatcher.addURI("com.example.app.provider", "table1/#", TABLE1_ITEM);
		uriMatcher.addURI("com.example.app.provider", "table2", TABLE2_DIR);
		uriMatcher.addURI("com.example.app.provider", "table2/#", TABLE2_ITEM);
	}

	@Override
	public Cursor query(Uri uri, String sortOrder) {
		
		switch (uriMatcher.match(uri)) {
		
		case TABLE1_DIR:
			// 查询table1表中所有数据
			break;
		case TABLE1_ITEM:
			// 查询table2表中单条数据
			break;
		case TABLE2_DIR:
			// 查询table2表中所有数据
			break;
		case TABLE2_ITEM:
			//  查询table2表中单条数据
			break;
		default:
			break;
		}
		....
	}

	...

}

You can see that four integer constants have been added to myprovider, of which table1_ Dir means to access all data in table1 table, table1_ Item means to access a single piece of data in table1, and table2_ Dir means to access all data in table2 table, table2_ Item means to access a single piece of data in table2 table. Then, in the static code block, we create an instance of urimatcher and call the adduri () method to pass in the expected content URI format. Note that wildcards can be used for the path parameters passed in here. Then, when the query () method is called, it will match the incoming URI object through the match () method of the urimatcher. If it is found that the URI format of a content in the urimatcher successfully matches the URI object, the corresponding user-defined code will be returned, and then we can judge what data the caller expects to access. The above code just takes the query () method as an example. In fact, insert (), update (), delete ()

The implementation of method is similar. They all carry the URI parameter, and then use the match () method of urimatcher to determine which table the caller expects to access, and then operate the data in the table accordingly.

The GetType () method is a method that all content providers must provide to obtain the MIME type corresponding to the URI object. The mime string corresponding to a content URI is mainly composed of three parts. Android specifies the following formats for these three parts:

So, for content://com.example.app.provider/table1 The content URI and its corresponding MIME type can be written as: vnd.android.cursor.dir/vnd.com.example.app.provider.table1

Now we can continue to improve the contents of myprovider. This time, we can implement the logic in the GetType () method. The code is as follows:

        @Override
	public String getType(Uri uri) {
		switch (uriMatcher.match(uri)) {
		case TABLE1_DIR:
			return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1";
		case TABLE1_ITEM:
			return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
		case TABLE2_DIR:
			return "vnd.android.cursor.dir/vnd.com.example.app.provider.table2";
		case TABLE2_ITEM:
			return "vnd.android.cursor.item/vnd.com.example.app.provider.table2";
		default:
			break;
		}
		return null;
	}

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>