1.内容提供者是Android四大组件之一,主要用于不同程序间实现数据共享。为什么内容提供者能够保护隐私数据,因为被请求访问的内容必须匹配对应的Uri才能获取到数据,我们当然不会对隐私数据添加Uri,所以使用内容提供者来进行不同进程间的数据共享。
2.内容提供者主要通过context的getContentResolver来操作数据,获取ContentResolver对象后使用insert(),delete(),update(),query()。其中uri的参数由两部分组成,authority和path。authority是authority名,path是表名。再加上一个协议头content:
3.访问其他程序中的数据,这里以获取联系人列表为例
public class ContentProviderGetContactActivity extends AppCompatActivity {
Listlist=new ArrayList<>();
private ArrayAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content_rrovider);
ListView listView= (ListView) findViewById(R.id.lv_contact);
adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,list);
listView.setAdapter(adapter);
if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_CONTACTS)!= PackageManager.PERMISSION_GRANTED){//获取联系人是危险权限所以需要运行时授权
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_CONTACTS},1);
}else{
getContacts();
}
}
private void getContacts(){
Cursor cursor=null;
try {
cursor=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);//获取联系人
if (cursor != null) {
while (cursor.moveToNext()) {
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
list.add(displayName + "\n" + number);
}
adapter.notifyDataSetChanged();
}else{
Toast.makeText(this,"获取到的联系人为空",Toast.LENGTH_SHORT).show();
}
}catch (Exception e){
}finally {
if (cursor!=null){
cursor.close();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 1:
if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
getContacts();
}else{
Toast.makeText(this,"您没有授权获取联系人",Toast.LENGTH_SHORT).show();
}
break;
}
}
4.创建自己的内容提供者,创建一个内容提供者
public class DatabaseProvider extends ContentProvider {
public static final int BOOK_DIR=0;
public static final int BOOK_ITEM=1;
public static final int CATEGORY_DIR=2;
public static final int CATEGORY_ITEM=3;
public static final String AUTHORITY="com.firstlinecode.provider";//定义内容提供则时候的authorityName,打开androidManifest.xml看一下就可以了
public static UriMatcher uriMatcher;
static {
uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);//可供外部访问的Uri的枚举
uriMatcher.addURI(AUTHORITY,"book",BOOK_DIR);
uriMatcher.addURI(AUTHORITY,"book/#",BOOK_ITEM);
uriMatcher.addURI(AUTHORITY,"category",CATEGORY_DIR);
uriMatcher.addURI(AUTHORITY,"category/#",CATEGORY_ITEM);
}
private SQLiteDatabase db;
public DatabaseProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
db=Connector.getDatabase();
int deleteRows=0;
switch (uriMatcher.match(uri)){
case BOOK_DIR:
deleteRows=db.delete("Book",selection,selectionArgs);
break;
case BOOK_ITEM:
String bookid=uri.getPathSegments().get(1);
deleteRows=db.delete("Book","id=?",new String[]{bookid});
}
return deleteRows;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)){
case BOOK_DIR:
return "vnd.android.dir/vnd.com.firstlinecode.book";//前半截表示book表所有的行,规定写法,后半截vnd+包名+表名
case BOOK_ITEM:
return "vnd.android.item/vnd.com.firstlinecode.book";//前半截表示book表中的某一行,规定写法,后半截vnd+包名+表名
}
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
db = Connector.getDatabase();
Uri uriReturn=null;
switch (uriMatcher.match(uri)){
case BOOK_DIR:
case BOOK_ITEM:
long bookid=db.insert("book",null,values);
uriReturn=Uri.parse("content://"+AUTHORITY+"/book/"+bookid);
break;
}
return uriReturn;
}
@Override
public boolean onCreate() {
db = Connector.getDatabase();
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
db = Connector.getDatabase();
Cursor cursor=null;
switch (uriMatcher.match(uri)){
case BOOK_DIR:
cursor=db.query("book",projection,selection,selectionArgs,null,null,sortOrder);
break;
case BOOK_ITEM:
String bookId=uri.getPathSegments().get(1);
cursor=db.query("book",projection,"id=?",new String[]{bookId},null,null,sortOrder);
break;
case CATEGORY_DIR:
cursor=db.query("book",projection,selection,selectionArgs,null,null,sortOrder);
break;
case CATEGORY_ITEM:
cursor=db.query("book",projection,selection,selectionArgs,null,null,sortOrder);
break;
}
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
db=Connector.getDatabase();
int updateRows=0;
switch (uriMatcher.match(uri)){
case BOOK_DIR:
updateRows=db.update("book",values,selection,selectionArgs);
break;
case BOOK_ITEM:
String newBookId=uri.getPathSegments().get(1);
updateRows=db.update("book",values,"id=?",new String[]{newBookId});
break;
}
return updateRows;
}
}
然后其他地方调用
public class ContentProviderCustomActivity extends AppCompatActivity implements View.OnClickListener {
private String newId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content_provider_custom);
findViewById(R.id.custom_insert).setOnClickListener(this);
findViewById(R.id.custom_update).setOnClickListener(this);
findViewById(R.id.custom_delete).setOnClickListener(this);
findViewById(R.id.custom_query).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.custom_insert:
Uri uri=Uri.parse("content://com.firstlinecode.provider/book");//定义内容提供则时候的authorityName,打开androidManifest.xml看一下就可以了
ContentValues values=new ContentValues();
values.put("name","第一行代码");
values.put("author","郭林");
values.put("price",20.0);
values.put("pages",400);
Uri newUri=getContentResolver().insert(uri,values);
newId = newUri.getPathSegments().get(1);
Toast.makeText(this,"新添加的数据的id为"+newId,Toast.LENGTH_SHORT).show();
break;
case R.id.custom_query:
Uri queryUri=Uri.parse("content://com.firstlinecode.provider/book");
Cursor cursor=getContentResolver().query(queryUri,null,null,null,null);
if (cursor!=null){
while (cursor.moveToNext()){
String name=cursor.getString(cursor.getColumnIndex("name"));
String author=cursor.getString(cursor.getColumnIndex("author"));
int pages=cursor.getInt(cursor.getColumnIndex("pages"));
double price=cursor.getDouble(cursor.getColumnIndex("price"));
Log.d("csc",name+author+pages+price);
}
cursor.close();
Toast.makeText(this,"数据查询成功",Toast.LENGTH_SHORT).show();
}
break;
case R.id.custom_update:
Uri updateUri=Uri.parse("content://com.firstlinecode.provider/book");
ContentValues contentValues=new ContentValues();
contentValues.put("price",40.0);
int updateRows=getContentResolver().update(updateUri,contentValues,null,null);
Toast.makeText(this,"改变的数据行为"+updateRows,Toast.LENGTH_SHORT).show();
break;
case R.id.custom_delete:
Uri deleteUri=Uri.parse("content://com.firstlinecode.provider/book");
int deleteRows=getContentResolver().delete(deleteUri,null,null);
Toast.makeText(this,"删除的数据行为"+deleteRows,Toast.LENGTH_SHORT).show();
break;
}
}