如有转载,请申明:
转载至 http://blog.csdn.net/qq_35064774/article/details/52614271
ContentProvider是安卓四大组件之一,但与其他三种组件相比,并不是很常用,但同样重要。
ContentProvider可以让应用之间相互共享资源,比通过公开的文件的共享方式更加安全和高效。一般来说,我们很少需要自己去编写一个ContentProvider,除非你是一个著名应用的开发者。但这并不意味着我们不应该学习如何编写。下面简单介绍一下ContentProvider的编写流程。
编写ContentProvider
首先这个类需要继承ContentProvider,然后在AndroidManifest.xml中配置
<provider
android:name="com.ittianyu.contentprovider.StudentContentProvider"
android:authorities="com.ittianyu.contentprovider.student"
android:enabled="true"
android:exported="true"></provider>
Name 为对应的ContentProvider类,authorities为访问ContentProvider的路径。
下面我把一个简单的ContentProvider实现类代码贴出来
package com.ittianyu.contentprovider;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
/**
* 学生内容提供者
*/
public class StudentContentProvider extends ContentProvider {
private static final int MATCH_SUCCESS = 1;
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
matcher.addURI("com.ittianyu.contentprovider.student", "insert", MATCH_SUCCESS);
}
public StudentContentProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if(MATCH_SUCCESS != matcher.match(uri)) {
throw new RuntimeException("路径错误.....");
}
System.out.println("数据插入成功");
return null;
}
@Override
public boolean onCreate() {
// TODO: Implement this to initialize your content provider on startup.
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO: Implement this to handle query requests from clients.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO: Implement this to handle requests to update one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
}
上面的代码中,除了insert方法,其他方法都是自动生成,没有改动过。
细心的你会发现里面还有一个自己手动写的UriMatcher matcher,这个对象是用来匹配uri的,因此你可以添加自定义路径来限制一些非法的请求。
比如上面的代码中在static代码块中
matcher.addURI("com.ittianyu.contentprovider.student", "insert", MATCH_SUCCESS);
就添加了路径”insert”。所以在请求这个ContentProvider是,传递的Uri中需要加上路径insert,具体的完整Uri看后面的调用类。
我们可以看到自动生成的方法insert、delete、update、query 对应的是数据的增删改查,熟悉数据库操作的肯定一看就明白了,这里不多啰嗦。
除了对数据操作的方法,还有一个getType,意如其名,这个方法是用来返回指定URI的MIME数据类型。若URI是单条数据,则返回的MIME数据类型以vnd.android.cursor.item开头;若URI是多条数据,则返回的MIME数据类型以vnd.android.cursor.dir/开头。
编写ContentProvider调用方法
/**
* 通过content provider 添加数据
*/
private void add() {
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.ittianyu.contentprovider.student/insert");
ContentValues values = new ContentValues();
resolver.insert(uri, values);
}
要和ContentProvider通信,我们就需要ContentResolver。
通过getContentResolver就可以获得ContentResolver对象。
有了对象,我们还需要先准备好Uri 和ContentValues。
uri 有固定的格式,以”content://”开头,然后加上要通信的地址,如果有路径,则在后面追加,比如这里通信路径为”com.ittianyu.contentprovider.student”,路径为”insert”,所以完整的uri文本为"content://com.ittianyu.contentprovider.student/insert"。
由于我们这里没有要插入的数据,所以直接传了一个没有数据的values。
然后调用insert(uri, values);方法就实现了调用方法。
常见应用场景
读取短信自动填写验证码、短信备份还原、读取联系人、联系人备份还原。