Android四大组件之ContentProvider(内容提供者)

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;
        }
    }

你可能感兴趣的:(Android四大组件之ContentProvider(内容提供者))