1、某些数据库在外面是不能使用的。
2、ContentProvider让A程序中的数据能让B程序使用
3、ContentProvider主要是共享数据。可以添加ContentObserver来观察数据的变化
4、<provider />中的authorities主要用于区分不同的provider
5、content://cn.itcast.aqlite.provider((/person)/id)
解析:
content:// ----->固定写法,必须有
cn.itcast.aqlite.provider: ------》这个应用的应用名
person: 表名
6、A应用通过B应用的ContentProvider访问B应用的数据库
7、使用ContentProvider查询的几种方式:
1)不带表名
2)只代表名
3)带表名和id
这个例子用的还是之前那个例子
1、SQLiteProvider
package com.example.provider;
import com.example.sqlitetest.DBOpenHelper;
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.widget.Switch;
public class SQLiteProvider extends ContentProvider {
private UriMatcher matcher;
private DBOpenHelper helper;
public static final int PERSON = 1;
public static final int PERSON_ID = 2;
private SQLiteDatabase db;
@Override
public boolean onCreate() {//第一次启动时执行,会长期驻留在后台,除非被杀死,否则不会再被执行..
matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI("com.example.provider", "person", PERSON);// 设置一个Uri,如果匹配到person,则返回1
matcher.addURI("com.example.provider", "person/#", PERSON_ID);
helper = new DBOpenHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
System.out.println("--------->query");
db = helper.getReadableDatabase();
switch (matcher.match(uri)) {
case PERSON_ID:
long id = ContentUris.parseId(uri);// 获取uri最后的id
// selection = "id=" + id; //将id添加到查询条件中.这种方式只能解决查询条件只用id的情况
selection = selection == null ? "id=" + id : selection
+ " AND id= " + id;// 这时候就能处理查询条件可以不仅仅有id的情况了
case PERSON:
return db.query("person", projection, selection, selectionArgs,
null, null, sortOrder);
default:
throw new RuntimeException("Uri不能匹配");
}
}
@Override
public String getType(Uri uri) {
switch (matcher.match(uri)) {
case PERSON_ID:
return "带了ID.操作指定person";
case PERSON:
return "没带ID.操作所有person";
default:
break;
}
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = helper.getWritableDatabase();
switch (matcher.match(uri)) {
case PERSON:
long id = db.insert("person", "id", values);// 插入记录,得到id
return ContentUris.withAppendedId(uri, id);
default:
throw new RuntimeException("表明非法");
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
switch (matcher.match(uri)) {
case PERSON_ID:
long id = ContentUris.parseId(uri);// 获取uri最后的id
// selection = "id=" + id; //将id添加到查询条件中.这种方式只能解决查询条件只用id的情况
selection = selection == null ? "id=" + id : selection
+ " AND id= " + id;// 这时候就能处理查询条件可以不仅仅有id的情况了
case PERSON:
return db.delete("person", selection, selectionArgs);
default:
throw new RuntimeException("Uri不能匹配");
}
}
/**
* 有时候可能会改不了...
* 不知道是为什么
*/
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = helper.getWritableDatabase();
switch (matcher.match(uri)) {
case PERSON_ID:
long id = ContentUris.parseId(uri);// 获取uri最后的id
// selection = "id=" + id; //将id添加到查询条件中.这种方式只能解决查询条件只用id的情况
selection = selection == null ? "id=" + id : selection
+ " AND id= " + id;// 这时候就能处理查询条件可以不仅仅有id的情况了
case PERSON:
// return db.delete("person", selection, selectionArgs);
return db.update("person", values, selection, selectionArgs);
default:
throw new RuntimeException("Uri不能匹配");
}
}
// @Override
// public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
// SQLiteDatabase db = helper.getWritableDatabase();
// switch (matcher.match(uri)) { // 用匹配器匹配传入的uri
// case PERSON_ID:
// long id = ContentUris.parseId(uri); // 获取uri最后的id
// selection = selection == null ? "id=" + id : selection + " AND id=" + id; // 构建查询条件
// case PERSON:
// return db.update("person", values, selection, selectionArgs);
// default:
// throw new RuntimeException("Uri不能识别: " + uri);
// }
// }
}
至于这个例子中的其他代码其实是和前面是一样的。谢了ContentProvider以后记得早AndroidManifest.xml中添加上相应的注册代码:
<provider android:name="com.example.provider.SQLiteProvider"
android:authorities="com.example.provider"
/>
2、B应用的ProviderTest
package com.example.test;
import com.example.pojo.Person;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
public class ProviderTest extends AndroidTestCase {
/**
* 这个程序的执行顺序:
* .class -> .dex -> .apk -> 安装 -> 开启进程(开启主线程) ->
* 创建ProviderTest对象 (成员变量的方式在这里getContext(),这时还没有getContext())-> setContext() -> 测试方法 -> getContext()
*/
public void test1() {
ContentResolver resolver = getContext().getContentResolver();//注意,这里不能讲resolver作为全局变量
ContentValues values = new ContentValues();
Uri parse = Uri.parse("content://com.example.provider");
resolver.insert(parse, values);
resolver.delete(parse, null, null);
resolver.update(parse, values, null, null);
resolver.query(parse, null, null, null, null);
/**
* content://com.example.provider :决定了访问那个应用的数据库
*/
}
public void testQuery(){
ContentResolver resolver = getContext().getContentResolver();
/**
* content://com.example.provider/person
* content:// 固定写法
* com.example.provider: authorities
* person: 表名
*/
// Uri uri = Uri.parse("content://com.example.provider/person");//不带id进行查询
Uri uri = Uri.parse("content://com.example.provider/person/10");//带上id进行查询
// Cursor c = resolver.query(uri, null, "id>?", new String[]{"50"}, null);
Cursor c = resolver.query(uri, null, null, null, null);
while(c.moveToNext()){
Person p = new Person(c.getInt(0), c.getString(1), c.getInt(2));
System.out.println(p);
}
}
public void testInsert(){
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://com.example.provider/person");
ContentValues values = new ContentValues();
values.put("name", "li kaifu");
values.put("balance", 12345);
Uri uri1 = resolver.insert(uri, values);//插入数据,并且得到数据的uri
System.out.println(uri1);
}
public void testUpdate(){
ContentResolver resolver = getContext().getContentResolver();
// Uri uri = Uri.parse("content://com.example.provider/person/102");//指定id,只修改某一条记录
Uri uri = Uri.parse("content://com.example.provider/person");//不指定id,将整张表都修改
ContentValues values = new ContentValues();
values.put("name", "kaifu lili");
values.put("balance", 9999);
resolver.update(uri, values, null, null);
}
public void testDelete(){
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://com.example.provider/person/104");
resolver.delete(uri, null, null);
}
public void testGetType(){
ContentResolver resolver = getContext().getContentResolver();
String type1 = resolver.getType(Uri.parse("content://com.example.provider/person"));
String type2 = resolver.getType(Uri.parse("content://com.example.provider/person/102"));
System.out.println(type1);
System.out.println(type2);
}
}
源码下载: