由于APP开发很少需要把自己的数据暴露出来,所以contentProvider不经常使用,下边就详细的记录一下怎么使用。
首先需要在自己的应用中重写SQLiteOpenHelper
public class DBHelper extends SQLiteOpenHelper {
// 数据库名
private static final String DATABASE_NAME = "finch.db";
// 表名
public static final String USER_TABLE_NAME = "user";
private static final int DATABASE_VERSION = 1;
//数据库版本号
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + USER_TABLE_NAME + "(_id integer primary key autoincrement,name varchar(20),money varchar(20))");
db.execSQL("insert into " + USER_TABLE_NAME + "(name,money) values(?,?)", new String[]{"李四", "3000"});
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 版本更新时
}
}
然后写一个类继承ContentProvider
public class AutoProvider extends ContentProvider {
//[1]定义一个路径的匹配器
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int QUERYSUCESS = 0;
private static final int INSERTSUCESS = 1;
private static final int UPDATESUCESS = 2;
private static final int DELETESUCESS = 3;
private DBHelper myOpenHelper;
// 这个就是你在xml中写的 android:authorities="cn.scu.myprovider" 千万不要写错了!!!
public static final String AUTOHORITY = "cn.scu.myprovider";
// 表名
public static final String USER_TABLE_NAME = "user";
//[2]添加一个静态代码块 在这个代码块里面添加匹配的规则
static{
sURIMatcher.addURI(AUTOHORITY,"query", QUERYSUCESS);
sURIMatcher.addURI(AUTOHORITY, "insert", INSERTSUCESS);
sURIMatcher.addURI(AUTOHORITY, "update", UPDATESUCESS);
sURIMatcher.addURI(AUTOHORITY, "delete", DELETESUCESS);
}
@Override
public boolean onCreate() {
myOpenHelper = new DBHelper(getContext());
return false;
}
//这个方法是被其他应用调用的
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
//通过这个方法对数据库进行查询的操作
int code = sURIMatcher.match(uri);
if (code == QUERYSUCESS ) {
//说明路径匹配成功
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
//对数据库进行查询操作
Cursor cursor = db.query(USER_TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
//自己主动的发一条消息 告诉系统 数据库被操作
getContext().getContentResolver().notifyChange(uri, null);
return cursor;
}else {
//说明路径匹配失败
throw new IllegalArgumentException("哥们 路径不正确,请检查路径");
}
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int code = sURIMatcher.match(uri);
if (code == INSERTSUCESS) {
//说明路径匹配成功
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
//对数据库进行增加一条记录
long insert = db.insert(USER_TABLE_NAME, null, values);
if (insert>0) {
//当数据库被人操作了 自己主动发一条消息
getContext().getContentResolver().notifyChange(uri, null);
}
Uri uri2 = Uri.parse("com.itheima.haha.insert/"+insert);
return uri2;
}else {
//说明路径匹配失败
throw new IllegalArgumentException("哥们 路径不正确,请检查路径");
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int code = sURIMatcher.match(uri);
if (code == DELETESUCESS) {
//说明路径匹配成功
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
int delete = db.delete(USER_TABLE_NAME, selection, selectionArgs);
if(delete>0){
//当数据库被人操作了 自己主动发一条消息
getContext().getContentResolver().notifyChange(uri, null);
}
return delete;
}else {
//说明路径匹配失败
throw new IllegalArgumentException("爷们 路径不正确,请检查路径");
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int code = sURIMatcher.match(uri);
if (code == UPDATESUCESS) {
//说明路径匹配成功
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
int update = db.update(USER_TABLE_NAME, values, selection, selectionArgs);
if (update>0) {
//当数据库被人操作了 自己主动发一条消息
getContext().getContentResolver().notifyChange(uri, null);
}
return update;
}else {
//说明路径匹配失败
throw new IllegalArgumentException("爷们 路径不正确,请检查路径");
}
}
}
为了让其他应用可以访问,你还需要在xml中这样写
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<provider
android:name=".contentProvider.AutoProvider"
android:authorities="cn.scu.myprovider"
android:exported="true"
/>
在本地你可以这样操作数据库
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn;
private Button btn1;
private Button btn2;
private Button btn3;
private DBHelper dbHelper;
public static final String USER_TABLE_NAME = "user";
private SQLiteDatabase writableDatabase;
private SQLiteDatabase readableDatabase;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.btn);
btn1 = findViewById(R.id.btn1);
btn2 = findViewById(R.id.btn3);
btn3 = findViewById(R.id.btn3);
btn.setOnClickListener(this);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
dbHelper = new DBHelper(getApplicationContext());
writableDatabase = dbHelper.getWritableDatabase();
readableDatabase = dbHelper.getReadableDatabase();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn://增加数据
ContentValues values = new ContentValues();
values.put("name", "zhangsan");
values.put("money", "234");
readableDatabase.insert(USER_TABLE_NAME, null, values);
break;
case R.id.btn1:// 更新数据
ContentValues values1 = new ContentValues();
values1.put("money", "1234");
readableDatabase.update(USER_TABLE_NAME, values1, "name=?", new String[]{"zhangsan"});
break;
case R.id.btn2://查询数据
// Cursor cursor= readableDatabase.query(USER_TABLE_NAME,null,null,null,null,null,null);
break;
case R.id.btn3: //删除数据
readableDatabase.delete(USER_TABLE_NAME,"name=?", new String[]{"李四"});
break;
}
Cursor cursor = readableDatabase.query(USER_TABLE_NAME, null, null, null, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
//把name和money取出来
String name = cursor.getString(1);
String money = cursor.getString(2);
System.out.println("=====name:" + name + "----" + money);
}
cursor.close();
}
}
}
下边就是本部分的重点了,第三方应用如何访问呢?
在三方的应用中
public class MainActivity extends AppCompatActivity {
private String uri_user = "content://cn.scu.myprovider/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//点击按钮向数据库增加一条记录
public void click1(View v) {
// [1]由于第一个应用的数据库内容已经通过内容提供者暴露出来 所以我可以直接通过内容解析者去访问
Uri uri = Uri.parse(uri_user + "/insert");
ContentValues values = new ContentValues();
values.put("name", "王五"); //key就是字段的名字 value就是值
values.put("money", "1000");
Uri insertUri = getContentResolver().insert(uri, values);
System.out.println(insertUri);
}
//点击按钮删除
public void click2(View v) {
Uri uri = Uri.parse(uri_user + "/delete");
int delete = getContentResolver().delete(uri, "name=?", new String[]{"王五"});
Toast.makeText(getApplicationContext(), "删除了" + delete + "行", 1).show();
}
//点击按钮更新
public void click3(View v) {
Uri uri = Uri.parse(uri_user + "/update");
ContentValues values = new ContentValues();
values.put("money", "10000");//更新钱
int update = getContentResolver().update(uri, values, "name=?", new String[]{"王五"});
Toast.makeText(getApplicationContext(), "更新了" + update + "行", 1).show();
}
//点击按钮查询数据库
public void click4(View v) {
// [1]由于第一个应用的数据库内容已经通过内容提供者暴露出来 所以我可以直接通过内容解析者去访问
Uri uri = Uri.parse(uri_user + "/query");
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
while (cursor.moveToNext()) {
// 把name和money取出来
String name = cursor.getString(1);
String money = cursor.getString(2);
System.out.println("第二个应用name:" + name + "----" + money);
}
}
最后,不要忘了在清单文件中添加权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />