如何创建一个ContentProvider,提供给其他App访问

一、概述
内容提供者是封装一套给其他APP访问此APP数据的接口,并提供安全的权限机制,如何数据不用提供给其他应用访问的话,使用数据库就可以了,内容提供者更加强调的是需要跨应用。

二、编码思路
1、使用SQliteOpenHelper类,创建一个数据库。
2、写一个类继承ContentPrivoder实现抽象方法
3、定义一套访问的此ContentPrivoder的唯一路径
4、用ContentResolver对象去访问ContentPrivoder进行增删改查

1、创建DBHelper类继承SqLiteOpenHelper类

package com.kuxiao.train.contentprovider.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBhelper extends SQLiteOpenHelper {

    private static DBhelper mDBhelper = null;
    private static final String DB_NAME = "myDB.db";//数据库名字
    private static final int DB_VERSION = 1;//数据库版本号
    //建表语句
    public static final String CREATE_TABLE = "create table user_info(_id Integer primary key autoincrement,"
            + "user_id Integer,user_name text,user_address text,user_password text,user_number Integer)";
    //删表语句
    public static final String DROP_TABLE = "drop table if exists user_info";

    private DBhelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    //单例模式
    public static DBhelper getInstance(Context context) {
        if (mDBhelper == null) {
            synchronized (new Object()) {
                if (mDBhelper == null) {
                    mDBhelper = new DBhelper(context);
                }
            }
        }
        return mDBhelper;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
           db.execSQL(CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
          db.execSQL(DROP_TABLE);
          db.execSQL(CREATE_TABLE);
    }

}

2、创建一个类继承ContentProvider类,实现方法,并定义好访问匹配

package com.kuxiao.train.contentprovider.db;

import android.content.ContentProvider;
import android.content.ContentUris;
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 UserContentProvider extends ContentProvider {

    private static final String TAG = "UserContentProvider";
    private DBhelper mDBhelper = null;
    // Uri匹配器
    private static final UriMatcher MATCHER = new UriMatcher(
            UriMatcher.NO_MATCH);
    public static final int USER = 1;// 操作单条数据
    public static final int USERS = 2;// 操作多条数据
    static {
        // 增加俩条匹配规则
        MATCHER.addURI("com.kuxiao.train.contentprovider.UserContentProvider",
                "user_info/#", USER);
        MATCHER.addURI("com.kuxiao.train.contentprovider.UserContentProvider",
                "user_info", USERS);
    }

    @Override
    public boolean onCreate() {
        mDBhelper = DBhelper.getInstance(getContext());
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        //
        Cursor cursor = null;
        SQLiteDatabase db = mDBhelper.getReadableDatabase();
        switch (MATCHER.match(uri)) {
        case USER:
            long id = ContentUris.parseId(uri);
            String select = "_id = " + id;
            if(selection != null && !selection.equals(""))
            {
                   select += "and" + selection;
            }
           cursor = db.query("user_info", projection, select, selectionArgs, null, null, sortOrder);
            break;
        case USERS:
            cursor = db.query("user_info", projection, selection, selectionArgs, null, null, sortOrder);
            break;
        }
        return cursor;
    }



    @Override
    public String getType(Uri uri) {

        switch (MATCHER.match(uri)) {
        case USER:

            return "vnd.android.cursor.item/com.kuxiao.train.contentprovider.UserContentProvider/user_info";

        case USERS:
            return "vnd.android.cursor.dir/com.kuxiao.train.contentprovider.UserContentProvider/user_info";
        }
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {

        Uri  resultUri = null;
        switch (MATCHER.match(uri)) {
        case USER:

            break;
        case USERS:
            SQLiteDatabase db = mDBhelper.getReadableDatabase();
            long id = db.insert("user_info", null, values);//返回插入影响数据库的行数
            resultUri = ContentUris.withAppendedId(uri, id);
            break;
        }
        Log.i(TAG, resultUri.toString());
        return resultUri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {

        int con = -1;
        int frag = MATCHER.match(uri);
        SQLiteDatabase db = mDBhelper.getWritableDatabase();
        switch (frag) {
        case USER:
            //解析客户端传过来的id
            long id = ContentUris.parseId(uri);
            String  vaule_name = "_id = " + id;
             if(selection != null &&!selection.equals("")) 
             {
                 //如果客户端传过来的选择语句不为空将进行累加  
                 vaule_name += "and" + selection; 
             }
             con =  db.delete("user_info", vaule_name, selectionArgs);
            break;
        case USERS: 
             con = db.delete("user_info", selection, selectionArgs);
            break;
        }
        db.close();
        return con;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
         int con = -1;
         // update user_info set name = ?,address = ? where id = ?;
         SQLiteDatabase db = mDBhelper.getWritableDatabase();
         switch (MATCHER.match(uri)) {
        case USER:
            long id = ContentUris.parseId(uri);
             String value_name = "_id = " + id;

             if(selection != null && !selection.equals(""))
             {
                   value_name += "and" + selection;
             }
            con =  db.update("user_info", values, value_name, selectionArgs);
            break;
        case USERS:
            con = db.update("user_info", values, selection, selectionArgs); 
            break;
        }
        db.close();
        Log.i(TAG, "----->>>影响的行数为 " +con);
        return con;
    }

}

3、单元测试

package test;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;

public class Test extends AndroidTestCase {

    public void insert() {
        // 获取ContentResolver对象
        ContentResolver contentResolver = getContext().getContentResolver();

        // 构建解析路径:content://// 单条
        // content:/// 多条
        Uri uri = Uri
                .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info");
        ContentValues values = new ContentValues();
        values.put("user_id", 3);
        values.put("user_name", "张万里");
        values.put("user_address", "dalian");
        values.put("user_password", "yw123456789");
        values.put("user_number", 953751759);
        contentResolver.insert(uri, values);

    }

    public void update() {
        // 获取ContentResolver对象
        ContentResolver resolver = getContext().getContentResolver();
        // 构建Uri content:// + 授权 + 表名
      Uri uri = Uri
        .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info/6");
        ContentValues values = new ContentValues();
        values.put("user_id", 2);
        values.put("user_name", "刘海洋");
        values.put("user_address", "beijing");
        values.put("user_password", "I love you liu haiyang");
        values.put("user_number", 123456789);
        resolver.update(uri, values, null, null);

    }

    public void delete() {
        // 获取ContentResolver对象
        ContentResolver resolver = getContext().getContentResolver();
        // 构建Uri content:// + 授权 + 表名
        Uri uri = Uri
                .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info");
        ContentValues values = new ContentValues();

        resolver.delete(uri, null, null);

    }
    public void query() {
        ContentResolver contentResolver = getContext().getContentResolver();
        Uri uri = Uri
                .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info");
        Cursor cursor = contentResolver.query(uri, null, null, null, null);
        while (cursor.moveToNext()) {


            Log.i("UserContentProvider", "------->>>>>>"
                    + cursor.getInt(cursor.getColumnIndex("user_id")));
            Log.i("UserContentProvider", "------->>>>>>"
                    + cursor.getString(cursor.getColumnIndex("user_name")));
            Log.i("UserContentProvider", "------->>>>>>"
                    + cursor.getString(cursor.getColumnIndex("user_address")));
            Log.i("UserContentProvider", "------->>>>>>"
                    + cursor.getString(cursor.getColumnIndex("user_password")));

            Log.i("UserContentProvider", "------->>>>>>"
                    + cursor.getInt(cursor.getColumnIndex("user_number")));

        }

    }
}

四、主意事项
1、在清单文件增加授权

<provider android:name=".db.UserContentProvider"
//授权一般是包名+类名            android:authorities="com.kuxiao.train.contentprovider.UserContentProvider"/>

2、定义访问路径标示符,操作单条与多条的区别

private static final UriMatcher MATCHER = new UriMatcher(
            UriMatcher.NO_MATCH);
    public static final int USER = 1;// 操作单条数据
    public static final int USERS = 2;// 操作多条数据
    static {
        // 增加俩条匹配规则
    //路径为:授权+数据库表名+标示符 (单条要在表名后加上/#号)
    MATCHER.addURI("com.kuxiao.train.contentprovider.UserContentProvider",
                "user_info/#", USER);
        MATCHER.addURI("com.kuxiao.train.contentprovider.UserContentProvider",
                "user_info", USERS);
    }

3、重写getType方法是操作单条还是多条的区别

@Override
    public String getType(Uri uri) {
    //根据传过来的uri解析 返回对应的字符串,参考开发文档
        switch (MATCHER.match(uri)) {
        case USER:

            return "vnd.android.cursor.item/com.kuxiao.train.contentprovider.UserContentProvider/user_info";

        case USERS:
            return "vnd.android.cursor.dir/com.kuxiao.train.contentprovider.UserContentProvider/user_info";
        }
        return null;
    }

4、通过内容解析者访问时,路径定义

// 构建Uri content:// + 授权 + 表名 
// 构建解析路径:content://// 单条
        // content:/// 多条
        Uri uri = Uri
                .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info/6");//单条
                Uri uri = Uri
                .parse("content://com.kuxiao.train.contentprovider.UserContentProvider/user_info"); //多条

五、特别说明:此都是小白成长记,有何不妥,欢迎指教。

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