ContentProvide简单使用

来源:互联网 发布:mac os x 10.13.1 cdr 编辑:程序博客网 时间:2024/06/06 02:31

#1,contentprovide的作用:

应用程序默认创建的数据库是私有的,别的应用默认不能访问,如果想把当前的引用程序的数据暴露给别的应用,就可以使用内容提供者。

#2,Contentprovide的简单使用:

创建两个项目,项目A和项目B

1,在A中首先创建一个数据库,创建数据库之前先创建一个数据库的帮助类继承SQLiteOpenHelper。


public class BankDBOpenHelper extends SQLiteOpenHelper{

    public BankDBOpenHelper(Context context) {
        super(context, "bank.db", null, 1);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table account (_id integer primary key autoincrement,name varchar(20),money varchar(20))");
       
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
       
    }

}
构造方法BankDBOpenHelper中,第一个参数是上下文,第二个参数是数据库的名称,第三个参数是游标工厂,第四个参数是数据库的版本号。继承SQLiteOpenHelper后重写oncreate方法,创建表。


2,创建一个类继承ContentProvide

首先内容提供者像activity一样,需要在清单文件中配置:

 <provider android:name="com.example.day09_01_contentprovider.BankDBBackDoor"
            android:authorities="com.heima.bank"
            android:exported="true">
        </provider>
authorities属性表示主机名,作用是当别的应用调用当前应用的数据时,作为一个验证标识,exported属性表示是否允许其他的应用访问当前的应用。

在类中首先创建作为匹配URI的标识和主机名结合使用:

private static final int SUCCESS = 1;
//如果uri匹配失败,返回默认值UriMatcher.NO_MATCH,也就是-1
 static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);static {uriMatcher.addURI("com.heima.bank", "account", SUCCESS);}在addURI方法中,第一个参数是主机名,第二个参数是路径,通常填写为表名,第三个参数表示匹配成功返回的值。接下来就是对数据库的增删改查的操作:@Override
 public Uri insert(Uri uri, ContentValues values) {
  int code = uriMatcher.match(uri);
  if (code == SUCCESS) {
   System.out.println("插入数据");
   BankDBOpenHelper helper = new BankDBOpenHelper(getContext());
   SQLiteDatabase db = helper.getWritableDatabase();
   db.insert("account", null, values);
   //通知观察者数据发生了变化
   getContext().getContentResolver().notifyChange(uri, null);
  }else {
   throw new IllegalArgumentException("口令错误");
  }
  return null;
 }

 @Override
 public int delete(Uri uri, String selection, String[] selectionArgs) {
  int code = uriMatcher.match(uri);
  if (code == SUCCESS) {
   System.out.println("删除数据");
   BankDBOpenHelper helper = new BankDBOpenHelper(getContext());
   SQLiteDatabase db = helper.getWritableDatabase();
   db.delete("account", selection, selectionArgs);
   //通知观察者数据发生了变化
   getContext().getContentResolver().notifyChange(uri, null);
  }else {
   throw new IllegalArgumentException("口令错误");
  }
  return 0;
 }

 @Override
 public int update(Uri uri, ContentValues values, String selection,
   String[] selectionArgs) {
  int code = uriMatcher.match(uri);
  if (code == SUCCESS) {
   System.out.println("更新数据");
   BankDBOpenHelper helper = new BankDBOpenHelper(getContext());
   SQLiteDatabase db = helper.getWritableDatabase();
   db.update("account", values, selection, selectionArgs);
   //通知观察者数据发生了变化
   getContext().getContentResolver().notifyChange(uri, null);
  }else {
   throw new IllegalArgumentException("口令错误");
  }
  return 0;
 }

 @Override
 public Cursor query(Uri uri, String[] projection, String selection,
   String[] selectionArgs, String sortOrder) {
  int code = uriMatcher.match(uri);
  if (code == SUCCESS) {
   System.out.println("查询数据");
   BankDBOpenHelper helper = new BankDBOpenHelper(getContext());
   SQLiteDatabase db = helper.getReadableDatabase();
   return db.query("account", projection, selection, selectionArgs, null, null, sortOrder);
   
  }else {
   throw new IllegalArgumentException("口令错误");
  }
 }
在项目B中,布局效果如下:

在代码中,首先获取内容解析器对象,利用解析器对数据进行操作,其中URI传入的对象正是在项目A中创建的UriMatcher中参数的拼接,在B中,content://作为内容提供者使用的一个标识。查询结束了别忘记关闭cursor,防止内存泄漏。


public void insert(View view){
  //得到内容提供者的解析器
  ContentResolver resolver = getContentResolver();
  Uri uri = Uri.parse("content://com.heima.bank/account");
  ContentValues values = new ContentValues();
  values.put("name", "zhangsan");
  values.put("money", 10000);
  //利用解析器添加数据
  resolver.insert(uri, values);
 }
 public void delete(View view){
  ContentResolver resolver = getContentResolver();
  Uri uri = Uri.parse("content://com.heima.bank/account");
  resolver.delete(uri, "name=?", new String[]{"zhangsan"});
 }
 public void update(View view){
  ContentResolver resolver = getContentResolver();
  Uri uri = Uri.parse("content://com.heima.bank/account");
  ContentValues values = new ContentValues();
  values.put("money", 20000);
  resolver.update(uri, values, "name=?", new String[]{"zhangsan"});
 }
 public void query(View view){
  ContentResolver resolver = getContentResolver();
  Uri uri = Uri.parse("content://com.heima.bank/account");
  Cursor cursor = resolver.query(uri, new String[]{"name","money"}, null, null, null);
  while (cursor.moveToNext()) {
   String name = cursor.getString(0);
   float money = cursor.getFloat(1);
   System.out.println(name+":::"+money);
  }
  cursor.close();
}

*************************内容观察者
当应用程序的数据被外部应用操作时,内容观察者可以监听到数据的变化并可以做出相应的操作
如上文被标注的代码:
                     //通知观察者数据发生了变化
            getContext().getContentResolver().notifyChange(uri, null);
首先获取内容解析器对象,调用notifyChange方法,第一个参数出入URI,第二个参数传入数据库内容变化时消息接收
的对象,也可以传null,创建一个新的应用根据URI进行监听,下面则是第二种方式
Uri uri = Uri.parse("content://com.heima.bank/account");//
  getContentResolver().registerContentObserver(uri, true, new ContentObserver(new Handler()) {
   @Override
   public void onChange(boolean selfChange) {
    System.out.println("我发现数据变化了");
    super.onChange(selfChange);
   }
   
  });
其中registerContentObserver的第二个参数表示依赖通知,如果URI前面满足的话就填true,需要全部满足的话就填false。
一般填true。比如:
             原URI路径:               content://com.heima.bank/account                     content://com.heima.bank/a

               content://com.heima.bank/ddd

               content://com.heima.bank/account

红色字体的填true,为部分匹配,蓝色的为全匹配。
































































原创粉丝点击