一、ContentProvider应用场景:
我们想在自己的应用中访问别的应用,或者说一些ContentProvider暴露给我们的一些数据, 比如 手机联系人,短信等!我们想对这些数据进行读取或者修改,这就需要用到ContentProvider了! 我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用 到ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!、
二、ContentProvider概念讲解


2.1 ContentProvider的URI:

主要分三个部分:scheme, authority and path。scheme表示上图中的content://, authority表示B部分,path表示C和D部分。
A部分:表示是一个Android内容URI,说明由ContentProvider控制数据,该部分是固定形式,不可 更改的。
B部分:是URI的授权部分,是唯一标识符,用来定位ContentProvider。格式一般是自定义 ContentProvider类的完全限定名称,注册时需要用到,如: com.example.transportationprovider
C部分和D部分:是每个ContentProvider内部的路径部分,C和D部分称为路径片段,C部分指向一个对 象集合,一般用表的名字,如:/trains表示一个笔记集合;D部分指向特定的记录, 如:/trains/122表示id为122的单条记录,如果没有指定D部分,则返回全部记录。
2.2 使用系统提供的ContentProvider(比如通讯录信息)
打开模拟器的file exploer/data/data/com.android.providers.contacts/databases/contact2.db 导 出后使用SQLite图形工具查看,三个核心的表:raw_contact表,data表,mimetypes表(具体请见上篇博客,这篇主要介绍自定义ContentProvider)
2.3 自定义ContentProvider
我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用到 ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!


三、代码实现
1、在分享数据的app中创建一个类,继承ContentProvider
实现对应的方法,也可以不实现,默认空实现,按需进行重写。
onCreate() 只执行一次,用于初始化Provider
insert() 插入 delete()删除 update()更新 qurey()查询
getType() 获得ContentProvider数据的MIMI类型
public class NameContentProvider extends ContentProvider {
//初始化一些常量
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private DBOpenHelper dbOpenHelper;
//为了方便直接使用UriMatcher,这里addURI,下面再调用Matcher进行匹配
static {
matcher.addURI("com.ttit.providers.myprovider", "test", 1);
}
@Override
public boolean onCreate() {
dbOpenHelper = new DBOpenHelper(this.getContext(), "test.db", null, 1);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
return null;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
switch (matcher.match(uri)) {
//把数据库打开放到里面是想证明uri匹配完成
case 1:
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
long rowId = db.insert("test", null, values);
if (rowId > 0) {
//在前面已有的Uri后面追加ID
Uri nameUri = ContentUris.withAppendedId(uri, rowId);
//通知数据已经发生改变
getContext().getContentResolver().notifyChange(nameUri, null);
return nameUri;
}
}
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return 0;
}
}
2、在AndroidManifest.xml对ContentProvider进行注册
<!-- 属性依次为:全限定类名,用于匹配的URI,是否共享数据 -->
<provider
android:name="com.ttit.core.provider.NameContentProvider"
android:authorities="com.ttit.providers.myprovider"
android:exported="true" />
3、使用UriMatchar,完成对uri的匹配
//1、初始化一些常量,UriMatcher
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private DBOpenHelper dbOpenHelper;
//2、为了方便直接使用UriMatcher,这里addURI,下面再调用Matcher进行匹配
//匹配返回标识码1,不匹配返回-1
static {
matcher.addURI("com.ttit.providers.myprovider", "test", 1);
}
//3、在下面需要匹配uri地方使用match方法
@Override
public Uri insert(Uri uri, ContentValues values) {
switch (matcher.match(uri)) {
//把数据库打开放到里面是想证明uri匹配完成
case 1:
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
long rowId = db.insert("test", null, values);
if (rowId > 0) {
//在前面已有的Uri后面追加ID
Uri nameUri = ContentUris.withAppendedId(uri, rowId);
//通知数据已经发生改变
getContext().getContentResolver().notifyChange(nameUri, null);
return nameUri;
}
}
return null;
}
4、ContentProvider2Activity.java代码
在另一个工程中,调用getContentResolve()方法获得resolve对象,再调用对应的操作方法即可
public class ContentProvider2Activity extends AppCompatActivity {
private Button btninsert;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cp_layout2);
btninsert = (Button) findViewById(R.id.btninsert);
//读取contentprovider 数据
final ContentResolver resolver = this.getContentResolver();
btninsert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put("name", "测试");
Uri uri = Uri.parse("content://com.ttit.providers.myprovider/test");
resolver.insert(uri, values);
Toast.makeText(getApplicationContext(), "数据插入成功", Toast.LENGTH_SHORT).show();
}
});
}
}
其他代码
cp_layout2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btninsert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="插入"/>
</LinearLayout>
DBOpenHelper.java
public class DBOpenHelper extends SQLiteOpenHelper {
final String CREATE_SQL = "CREATE TABLE test(_id INTEGER PRIMARY KEY AUTOINCREMENT,name)";
public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
int version) {
super(context, name, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_SQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}