一、什么是ContentProvider?
ContentProvider在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。
ContentProvider是Android中的四大组件之一,可以将应用中的数据对外进行共享
ContentProvider将数据的访问方式统一,不必针对不同数据类型采取不同的访问策略
ContentProvider将数据封装,只暴露出我们希望提供给其他程序的数据
ContentProvider中数据更改可被监听
二、什么是ContentResolver?
ContentResolver是数据调用者,ContentProvider将数据发布出来后,通过ContentResolver对象结合Uri进行使用
通过ContentResolver可以调用ContentProvider的增、删、改、查操作
三、为什么要学习ContentProvider&ContentResolver?
1.多媒体数据库专门存储手机中的图片、音频、视频的媒体信息
2.当我们想获得手机中的音频信息时,不使用多媒体数据库、我们只能全盘递归,来寻找所需的音频信息
3.Android系统通过ContentProvider将多媒体数据共享出来、其他APP(调用者)只通过ContentResolver获取所需数据即可
四、什么是Uri?
URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。
Uri写法:content://com.android.contacts/contacts
content:此部分是固定写法,用来表明这是一个Uri
com.android.contacts:此部分指定了要访问的资源的存放地址即包名
contacts:此部分指定了要访问资源的路径
五、ContentProvider、ContentResolver用法:
- 使用SQLite技术、创建好数据库和数据表;
- 新建类继承ContentProvider;
- 创建UriMacther定义Uri规则;
- 重写六个抽象方法
- 在AndroidManifest中注册provider
- ContentResolver对ContentProvider共享的数据进行增、删、改、查
六 、ContentProvider&ContentResolver使用实例:
使用ContentProvider和ContentResolver进行跨进程通信。
1.新建一个工程project,创建数据库,新建一个DataBaseProvider 继承ContentProvider。重写里面的六个方法:
package com.test.project.myapplication;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
public class DataBaseProvider extends ContentProvider {
public static final int STUDENT_DIR = 0;
public static final int STUDENT_ITEM = 1;
public static final String AUTHORITY = "com.test.project.myapplication";
private static UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, "student", STUDENT_DIR);
uriMatcher.addURI(AUTHORITY, "student/#", STUDENT_ITEM);
}
private MyDataBaseHelper dbHelper;
public DataBaseProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
dbHelper = new MyDataBaseHelper(getContext(), "Student.db", null, 2);
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("student",selection,selectionArgs);
return 1;
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
switch (uriMatcher.match(uri)) {
case STUDENT_DIR:
return "vnd.android.cursor.dir/vnd.com.test.project.myapplication.student";
case STUDENT_ITEM:
return "vnd.android.cursor.item/vnd.com.test.project.myapplication.student";
}
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO: Implement this to handle requests to insert a new row.
SQLiteDatabase db = dbHelper.getReadableDatabase();
Uri uriReturn = null;
switch (uriMatcher.match(uri)) {
case STUDENT_DIR:
case STUDENT_ITEM:
long newStudentId = db.insert("student", null, values);
uriReturn = Uri.parse("content://" + AUTHORITY + "/student/" + newStudentId);
break;
}
return uriReturn;
}
@Override
public boolean onCreate() {
// TODO: Implement this to initialize your content provider on startup.
dbHelper = new MyDataBaseHelper(getContext(), "Student.db", null, 2);
Log.e("onCreate: ", "-----------------------");
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO: Implement this to handle query requests from clients.
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = null;
switch (uriMatcher.match(uri)) {
case STUDENT_DIR:
cursor = db.query("student", projection, selection, selectionArgs, null, null, sortOrder);
break;
case STUDENT_ITEM:
String studentId = uri.getPathSegments().get(1);
cursor = db.query("student", projection, "id=?", new String[]{studentId}, null, null, sortOrder);
break;
default:
break;
}
// Log.e("query: ", "-----------------------");
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO: Implement this to handle requests to update one or more rows.
SQLiteDatabase db=dbHelper.getWritableDatabase();
int updateRows=0;
switch (uriMatcher.match(uri)){
case STUDENT_DIR:
updateRows=db.update("student",values,selection,selectionArgs);
break;
case STUDENT_ITEM:
updateRows=db.update("student",values,selection,selectionArgs);
break;
default:
break;
}
return updateRows;
}
}
2.新建一个工程project,布置其MainActivity代码。
在MainActivity.java中通过Button点击事件使用ContentResolver获取上面建好的project的数据
代码如下:
public class Main1Activity extends AppCompatActivity implements View.OnClickListener {
private Button queryBtn;
private Button insertBrn;
private Button updateBtn;
private Button deleteBtn;
private EditText inputEd;
private EditText inputEd2;
private String newId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
bindId();
}
private void bindId() {
queryBtn=findViewById(R.id.query_res_btn);
insertBrn=findViewById(R.id.insert_res_btn);
updateBtn=findViewById(R.id.update_res_btn);
deleteBtn=findViewById(R.id.delete_res_btn);
inputEd=findViewById(R.id.input_ed);
inputEd2=findViewById(R.id.input_ed2);
queryBtn.setOnClickListener(this);
insertBrn.setOnClickListener(this);
updateBtn.setOnClickListener(this);
deleteBtn.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.query_res_btn:
//查询数据
Uri uri1=Uri.parse("content://com.test.project.myapplication/student");
Cursor cursor=getContentResolver().query(uri1,null,null,null,null);
if (cursor!=null){
while (cursor.moveToNext()){
String name=cursor.getString(cursor.getColumnIndex("name"));
Log.e( "name: ",name );
}
cursor.close();
}
break;
case R.id.insert_res_btn:
//插入数据
String name=inputEd.getText().toString();
Uri uri2=Uri.parse("content://com.test.project.myapplication/student");
ContentValues values=new ContentValues();
values.put("name",name);
Uri newUri=getContentResolver().insert(uri2,values);
newId=newUri.getPathSegments().get(1);
break;
case R.id.update_res_btn:
//修改数据
Uri uri3=Uri.parse("content://com.test.project.myapplication/student");
String newd=inputEd.getText().toString();
String old=inputEd2.getText().toString();
ContentValues values1=new ContentValues();
values1.put("name",newd);
getContentResolver().update(uri3,values1,"name=?",new String[]{old});
break;
case R.id.delete_res_btn:
//删除数据
String deld=inputEd.getText().toString();
Uri uri4=Uri.parse("content://com.test.project.myapplication/student"+newId);
ContentResolver resolver=getContentResolver();
resolver.delete(uri4,"name=?",new String[]{deld});
break;
}
}
}