Content Provider实现跨应用数据库共享

调用相册,调用音乐等(上一遍已经介绍了)。这是怎么实现的呢?其实就是ContentProvider的功劳。系统封装好了ContentProvider,而我们只需要调用就行。
而现在我们需要自己对应用建立ContentProvider,以供别的应用访问。
结合实例:应用A要访问应用B 的数据库。

1:新建ContentProvider
1:new--->Other--->Content Provider ,新建时:URI Authorities代表主机名,组成建议这样的:包名+自定义名。
新建完成后系统会重写多个方法,接下来我们需要做的就是对这些方法做具体的实现。

2:实现方法:
实现以下方法,前提需要实现了SQLiteOpenHelper等创建数据库的操作,具体可参我的一篇文章(下面的例子也就是基于这篇文章里所创建的数据库):已创建的数据库

直接上代码:

假设应用为 A

public class MyContentProvider extends ContentProvider {
    private SQLiteUtil sqLiteUtil;
    //根据uri匹配
    private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
    static{
        //可有多个主机名,以便访问多个表
        MATCHER.addURI("com.index.test.sqlitetest.conp","user_info",1);//查询全表数据
        MATCHER.addURI("com.index.test.sqlitetest.conp","user_info/#",2);//根据唯一标识符查询
    }
    public MyContentProvider() {
    }

    @Override
    public String getType(Uri uri) {

        //系统回调,该方法会区分查询是全表查询还是单条数据查询,写法固定
        switch (MATCHER.match(uri)){
            case 1:
                return "vnd.android.cursor.dir/user_info";//必须以vnd开头
            case 2:
                return "vnd.android.cursor.item/user_info";//必须以vnd开头
        }
        return null;
    }

    //selection是查询条件,selectionArgs是要查询具体条件值,返回的是对数据库的影响行数
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db = sqLiteUtil.getWritableDatabase();
        //判断查询条件,要判断的值
        switch (MATCHER.match(uri)){
            case 1:
                return db.delete("user_info",selection,selectionArgs);
            case 2:
                long rowid = ContentUris.parseId(uri);//获取表的id
                String where = "_id = "+rowid;
                if (selection!=null && !selection.equals("")){
                    where = selection+" and "+where;
                }
                return db.delete("user_info",where,selectionArgs);
        }
        return 0;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase db = sqLiteUtil.getWritableDatabase();
        switch(MATCHER.match(uri)){
            case 1:
                long rowid = db.insert("user_info",null,values);
                return ContentUris.withAppendedId(uri,rowid);
            default:
                break;
        }
        return null;
    }

    @Override
    public boolean onCreate() {
        sqLiteUtil = new SQLiteUtil(this.getContext(),2);
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = sqLiteUtil.getReadableDatabase();
        switch (MATCHER.match(uri)){
            case 1:
                return db.query("user_info",projection,selection,selectionArgs,null,null,sortOrder);
            case 2:
                long rowid = ContentUris.parseId(uri);
                String where = "_id = "+rowid;
                if (selection!=null && !selection.equals("")){
                    where = selection +" and "+ where;
                }
                return db.query("info_user",projection,where,selectionArgs,null,null,sortOrder);
        }
        return null;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        SQLiteDatabase db = sqLiteUtil.getWritableDatabase();
        switch (MATCHER.match(uri)){
            case 1:
                return db.update("user_info",values,selection,selectionArgs);
            case 2:
                long rowid = ContentUris.parseId(uri);
                String where = "_id = "+rowid;
                if (selection!=null && !selection.equals("")){
                    where = selection +" and "+ where;
                }
                return  db.update("user_info",values,where,selectionArgs);
        }
        return 0;
    }
}

2:B访问A中的数据库

上面已经创建好了应用 AContentProvider ,现在我们从另外一个应用(假设应用为 B )中访问A 的数据库:
其实也很简单:
B 中通过A 主机名获取Uri ,通过getContentResolver()获得ContentResolver,通过ContentResolver执行数据库操作。

实例: B 获得Auser_info表的所有数据;点击往user_info表中添加一条数据:

public class ProviderActivity extends AppCompatActivity {

    private Button button1,button2;
    private TextView textView1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_provider);
        button1 = (Button)findViewById(R.id.getUser);
        button2 = (Button)findViewById(R.id.add);
        textView1 = (TextView)findViewById(R.id.showProvider);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //“com.index.test.sqlitetest.conp”是A中provider的主机名,“user_info”是数据库表,如果需要查询单条数据库,只需要在“user_info”后加上id即可,如“/user_info#3”,A中的provider会自动判断是单条查询还是全表查询
                Uri uri = Uri.parse("content://com.index.test.sqlitetest.conp/user_info");
                //获取ContentResolver ,用来执行数据库操作
                ContentResolver contentResolver = getContentResolver();
                //ContentResolver执行数据库操作,返回类型为Cursor 的结果集
                Cursor c = contentResolver.query(uri, null, null, null, null);
                //读取并显示数据
                StringBuffer stringBuffer = new StringBuffer();
                while (c.moveToNext()){
                    stringBuffer.append(c.getString(0)+"\n");
                    stringBuffer.append(c.getString(1)+"\n");
                    stringBuffer.append(c.getString(2)+"\n");
                    stringBuffer.append(c.getString(3)+"\n");
                    stringBuffer.append(c.getString(4)+"\n");
                }
                textView1.setText(stringBuffer.toString());
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addUser();
            }
        });
    }

    //添加操作
    public void addUser(){
    //原理同上
        Uri uri = Uri.parse("content://com.index.test.sqlitetest.conp/user_info");
        ContentResolver contentResolver = getContentResolver();
        ContentValues contentValues = new ContentValues();
        contentValues.put("name","xiaosheng");
        contentValues.put("age","20");
        contentValues.put("imgUrl","地址");
        contentValues.put("pwd", "admin");
        contentResolver.insert(uri, contentValues);
    }
    }

你可能感兴趣的:(数据库,android,应用)