1、ContentProvider是Android系统的四大组件之一,主要用于在不同的应用程序之间实现数据共享。
ContentProvider 以某种Uri 的形式对外提供数据,允许其他应用访问或修改数据,其他应用程序使用ContentResolver 根据Uri访问操作指定数据。
2、. ContentProvider 使用表的形式来组织数据,无论数据的来源是什么,ContentProvider都会认为是一种表,然后把数据组织成表格。
. ContentProvider提供的方法:query(查询)、insert(插入)、update(更新)、delete(删除)、getType(得到数据类型)、onCreate(创建数据时调用的回调函数)
. 每个ContentProvider都有一个公共的Uri,这个Uri用于表示这个ContentProvider所提供的数据。
3、Uri : 为系统的每一个资源给其一个名字,它由权限和路径组成,为了避免冲突,权限通常使用应用包名。
Uri uri = Uri.parse("content://com.wxb.app.provide/table/122”);
. A(content://) 标准前缀,用于说明ContentProvider 控制这些数据,无法改变
. B(com.wxb.app.provide) : Uri 标识, 包名
. C (table):路径 ,通俗 就是操作数据数据库表的名字
. D (122): 操作的ID
4、获取系统联系人电话
//参数1 为管理联系人的Uri,后面的条件填写null 为查询全部
Cursor cursor = contentResolver.query(CallLog.Calls.CONTENT_URI, null, null, null, null);
//首先获得 ContentResolver对象
ContentResolver contentResolver = getContentResolver();
//alt+ 回车 第二次添加的是权限的检查,6.0 不检查 系统崩溃
if (ActivityCompat.checkSelfPermission(this,Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
/*
*接着通过 ContentResolver获得Cursor对象,调用它的查询方法
* 第一参数:系统的通话记录的Uri
*/
Cursor cursor = contentResolver.query(CallLog.Calls.CONTENT_URI, null, null, null, null);
//操作这个 cursor
while (cursor.moveToNext()){
//打印电话号码
String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
Log.d(TAG,"onclick"+ number);
if (number.isEmpty()){
Log.d(TAG,"onclick - null");
}
}
break;
}
//获得Cursor对象(游标)就可以使用了。
自定义ContentProvider 必须进行注册 ,添加权限
5、常用的Uri : 管理联系人邮箱Uri ,SD卡音频文件Uri ,SD卡视频Uri
6、 写数据库
1> 创建MyOpenHelper 类继承 SQLiteOpenHelper
public class MyOpenHelper extends SQLiteOpenHelper {
private static final String CREAT_TABLE_PERSON = "create table person (id integer primary key autoincrement,name text,age integer)";
public MyOpenHelper(Context context,String name, SQLiteDatabase.CursorFactory factory, intversion) {
super(context,name, factory,version);
}
/**
* autoincrement :自增
*
* onCreate : 是创建数据库
* execSQL : 执行 Sql语句
*
*
*/
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(CREAT_TABLE_PERSON);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, inti, int i1) {
}
}
2>
/**
* 提供数据库存储的方法。
* 在使用之前首先指定当前的Uri是什么
* 还需要一个UriMatcher用来匹配 我们的Uri 的。
* 还需要我们刚写好的数据库。 MyOpenHelper
* 还需要一个数据库的操作类 SQLiteDatabase
* 写一个静态代码块设置一下 UriMatcher
*
* 然后在onCreate的方法里创建数据库
*
* 插入一条数据,别的应用程序才能查询
*
* 在提供一个查询的方法
*/
public class MyProviderextends ContentProvider{
private static final StringPACKAGE_NAME ="com.zhenzhoukeji.myprovider";
private static UriMatcher uriMatcher;
private MyOpenHelper myOpenHelper;
private SQLiteDatabase sqLiteDatabase;
static {
uriMatcher =new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PACKAGE_NAME,"person",0);
//如果我们传入的uri是以包名+表明这样的结构,表明是person,那么我们返回的code就是0
}
@Override
public boolean onCreate() {
/**
* 第一参数是 Context对象 ,第二个是是数据库的名。第四个数据库的版本,
*/
myOpenHelper =new MyOpenHelper(getContext(),"database",null,1);
sqLiteDatabase =myOpenHelper.getReadableDatabase();
ContentValues contentValues = newContentValues();
contentValues.put("name","xiaobao");
contentValues.put("age","25");
sqLiteDatabase.insert("person",null,contentValues);
return true;//ture 代表初始化完成
}
@Nullable
@Override
public Cursorquery(@NonNullUri uri, @Nullable String[] strings,@Nullable String s,@Nullable String[] strings1,@Nullable String s1) {
int code =uriMatcher.match(uri);
switch (code){
case 0://代表我们查的person
Cursor cursor = sqLiteDatabase.query("person",null,null,null,null,null,null);
return cursor;
}
return null;
}
@Nullable
@Override
public StringgetType(@NonNullUri uri) {
return null;
}
@Nullable
@Override
public Uriinsert(@NonNullUri uri, @Nullable ContentValues contentValues) {
return null;
}
@Override
public int delete(@NonNullUri uri, @Nullable String s,@Nullable String[] strings) {
return 0;
}
@Override
public int update(@NonNullUri uri, @Nullable ContentValues contentValues,@Nullable String s,@Nullable String[] strings) {
return 0;
}
}
3>添加权限
android:name=".MyProvider"
android:exported="true”//允许其他应用访问
/>
4> 读取权限
/**
* 这里实际是查询自己应用的数据库,Uri需要自己写
*/
Uri uri = Uri.parse("content://com.zhenzhoukeji.myprovider/person");
Cursor myCursor = getContentResolver().query(uri,null,null,null,null);
//如果Cursor有下一条数据的话
while (myCursor.moveToNext()){
String name = myCursor.getString(myCursor.getColumnIndex("name"));
int age = myCursor.getInt(myCursor.getColumnIndex("age"));
Log.d(TAG,"onclick - "+ name + age);
}
myCursor.close();