一、概述
内容提供者是封装一套给其他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"); //多条
五、特别说明:此都是小白成长记,有何不妥,欢迎指教。