zoukankan      html  css  js  c++  java
  • Android中内容提供者ContentProvider的详解

    1.什么是ContentProvider

    首先,ContentProvider(内容提供者)是android中的四大组件之一,但是在一般的开发中,可能使用的比较少。 ContentProvider为不同的软件之间数据共享,提供统一的接口。也就是说,如果我们想让其他的应用使用我们自己程序内的数据,就可以使用ContentProvider定义一个对外开放的接口,从而使得其他的应用可以使用咱们应用的文件、数据库内存储的信息。当然,自己开发的应用需要给其他应用共享信息的需求可能比较少见,但是在Android系统中,很多系统自带应用,比如联系人信息,图片库,音频库等应用,为了对其他应用暴露数据,所以就使用了ContentProvider机制。所以,我们还是要学习ContentProvider的基本使用,在遇到获取联系人信息,图片库,音频库等需求的时候,才能更好的实现功能

    2.如何定义一个ContentProvider

    Android系统为了让我们更好的对外暴露数据,提供了统一的接口,所以定义了抽象类ContentProvider,因此,如果我们想对外提供数据,我们需要继承ContentProvider,并且实现下面的这几个方法:
    onCreate() 当我们的provider初始化时被调用,我们应该在这个方法里面完成部分初始化操作 query() 查询方法,用于给调用者返回数据 insert() 插入操作,用于让外部应用插入数据到内容提供者中 update() 更新操作,用于更新内容提供者的数据 delete() 用于删除数据 getType 返回内容提供者的MIME Type
    上面这些方法,当我们继承自ContentProvider的时候,eclipse会自动的给我们添加,但是这并不代表我们每个方法都需要自定义实现。如果我们只希望给其他应用提供数据,而不允许其他应用修改我们的数据,那么我们只需要实现onCreate(),getType()和query()这三个方法就可以了,其他的三个方法我们可以根据业务需求,实现或者是不实现。
    因为一般使用ContentProvider向外部暴露数据库的信息,因此,本篇将以使用ContentProvider向其他应用暴露数据库信息为例,讲解ContentProvider的基本使用。
    Android中SQLite数据库的创建和使用,本篇不再介绍,不清楚的请看这篇文章 SQLite数据库的简单实用

    假设读者已经学会了SQLite数据库的使用,并且已经建立好了数据库,下面我们开始写我们的ContentProvider。 因为注释解析的比较详细,所以就不过多解释了

      1 /**
      2  * 内容提供者
      3  * 
      4  * @author ZhaoKaiQiang
      5  * @time 2014年6月6日
      6  */
      7 public class StudentProvider extends ContentProvider {
      8     // 数据库操作类,用于获取SQLiteDatabase
      9     private MyDbOpenHelper dbHelper;
     10 
     11     private static final int STUDENT = 1;
     12     private static final int STUDENTS = 2;
     13 
     14     // UriMatcher类是一个很重要的类,因为我们需要根据传入的uri,来判断执行相对应的操作
     15     private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
     16 
     17     // 静态代码块用于初始化MATCHER需要匹配的uri
     18     static {
     19         // MATCHER.addURI(主机名(用于唯一标示一个ContentProvider,这个需要和清单文件中的authorities属性相同),路径(可以用来表示我们要操作的数据,路径的构建应根据业务而定),返回值(用于匹配uri的时候,作为匹配的返回值));
     20         MATCHER.addURI("com.example.mydbdemo.StudentProvider", "student", STUDENTS);
     21         MATCHER.addURI("com.example.mydbdemo.StudentProvider", "student/#", STUDENT);
     22     }
     23 
     24     // 进行数据的初始化操作
     25     @Override
     26     public boolean onCreate() {
     27         dbHelper = new MyDbOpenHelper(getContext());
     28         return false;
     29     }
     30 
     31     // 查询
     32     // 如果uri为        content://com.example.mydbdemo.StudentProvider/student
     33     // 则代表查询所有的student表内的数据
     34     // 如果uri为        content://com.example.mydbdemo.StudentProvider/student/6
     35     // 则代表查询student表内id=6的数据
     36     @Override
     37     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
     38 
     39         SQLiteDatabase db = dbHelper.getReadableDatabase();
     40         //判断传入的uri到底匹配哪一个,从而实现不同的业务需求
     41         switch (MATCHER.match(uri)) {
     42         //查询全部的学生信息
     43         case STUDENTS:
     44             //db.query(表明, 要查询的列(是一个String数组), where条件, where条件中的参数, groupBy, having, sortOrder);
     45             return db.query("student", projection, selection, selectionArgs, null, null, sortOrder);
     46         //查询某一个id对应的学生的信息
     47         case STUDENT:
     48             //取出我们要查询的数据的id
     49             long id = ContentUris.parseId(uri);
     50             String where = "id=" + id;
     51             //将selection查询信息拼接到我们的where条件中
     52             if (selection != null && !"".equals(selection)) {
     53                 where = selection + " and " + where;
     54             }
     55             return db.query("student", projection, where, selectionArgs, null, null, sortOrder);
     56         //如uri不匹配,抛出不合法参数的异常
     57         default:
     58             throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
     59         }
     60 
     61     }
     62 
     63     // 插入
     64     @Override
     65     public Uri insert(Uri uri, ContentValues values) {
     66         SQLiteDatabase db = dbHelper.getWritableDatabase();
     67         switch (MATCHER.match(uri)) {
     68         case STUDENTS:
     69             long id = db.insert("student", "name", values);
     70             return ContentUris.withAppendedId(uri, id);
     71         default:
     72             throw new IllegalArgumentException("Uri不匹配");
     73         }
     74 
     75     }
     76 
     77     //删除数据
     78     @Override
     79     public int delete(Uri uri, String selection, String[] selectionArgs) {
     80         SQLiteDatabase db = dbHelper.getWritableDatabase();
     81         int count = 0;
     82         switch (MATCHER.match(uri)) {
     83         case STUDENTS:
     84             count = db.delete("student", selection, selectionArgs);
     85             return count;
     86 
     87         case STUDENT:
     88             long id = ContentUris.parseId(uri);
     89             String where = "id=" + id;
     90             if (selection != null && !"".equals(selection)) {
     91                 where = selection + " and " + where;
     92             }
     93             count = db.delete("student", where, selectionArgs);
     94             return count;
     95 
     96         default:
     97             throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
     98         }
     99     }
    100 
    101     //更新数据
    102     @Override
    103     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    104         SQLiteDatabase db = dbHelper.getWritableDatabase();
    105         int count = 0;
    106         switch (MATCHER.match(uri)) {
    107         case STUDENTS:
    108             count = db.update("student", values, selection, selectionArgs);
    109             return count;
    110 
    111         case STUDENT:
    112             long id = ContentUris.parseId(uri);
    113             String where = "id=" + id;
    114             if (selection != null && !"".equals(selection)) {
    115                 where = selection + " and " + where;
    116             }
    117             count = db.update("student", values, where, selectionArgs);
    118             return count;
    119 
    120         default:
    121             throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
    122         }
    123     }
    124 
    125     // 用于获取MIME Type
    126     @Override
    127     public String getType(Uri uri) {
    128         switch (MATCHER.match(uri)) {
    129         case STUDENT:
    130             return "vnd.android.cursor.item/student";
    131         case STUDENTS:
    132             return "vnd.android.cursor.dir/student";
    133         default:
    134             throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
    135         }
    136 
    137     }
    138 
    139 }

    我们在定义好我们的ContentProvider之后,因为ContentProvider数据四大组件之一,因此我们还需要在AndroidManifest清单文件中进行注册才能使用,下面是注册信息

    1 <!-- 不要忘记exported这个属性,如果不加,可能会导致外部程序访问失败,错误信息为权限拒绝 -->
    2          <!-- authorities这个属性就是我们在ContentProvider中使用的addURI方法时的第一个参数的取值 -->
    3         <provider
    4             android:name="com.example.mydbdemo.StudentProvider"
    5             android:exported="true"
    6             android:authorities="com.example.mydbdemo.StudentProvider" >
    7         </provider>

    注意,provider的声明和activity一样,都是在application节点进行声明的。
    至此,我们就完成了我们自己的ContentProvider的生命,其他的应用现在就可以使用我们往外部暴露的数据信息了。

    3.外部应用如何使用我们的ContentProvider

    我们已经定义好了我们自己的ContentProvider,那么外部应用如何调用呢? 下面,我将新建一个测试单元工程,完成对ContentProvider的各个方法的测试
    添加方法测试

     1 //使用ContentProvider添加数据的测试
     2     public void testadd() throws Throwable {
     3         //获取ContentResolver对象,完成对ContentProvider的调用
     4         ContentResolver contentResolver = this.getContext().getContentResolver();
     5         //构建我们的uir,这个uri
     6         Uri insertUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student");
     7         ContentValues values = new ContentValues();
     8         values.put("name", "zhaokaikai");
     9         values.put("age", 91);
    10         values.put("school", "bbbb");
    11         //返回值为我们刚插入进入的数据的uri地址
    12         Uri uri = contentResolver.insert(insertUri, values);
    13         Log.i(TAG, uri.toString());
    14     }

    删除方法测试

    1 //使用ContentProvider删除数据的测试
    2     public void testDelete() throws Throwable {
    3         ContentResolver contentResolver = this.getContext().getContentResolver();
    4         //删除id为6的学生信息
    5         Uri deleteUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student/6");
    6         contentResolver.delete(deleteUri, null, null);
    7     }

    修改方法测试

     1 //使用ContentProvider更新数据的测试
     2     public void testUpdate() throws Throwable {
     3         ContentResolver contentResolver = this.getContext().getContentResolver();
     4         //更新id = 6 的学生信息
     5         Uri updateUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student/6");
     6         ContentValues values = new ContentValues();
     7         values.put("name", "testUp");
     8         values.put("age", "101");
     9         values.put("school", "ccccc");
    10         contentResolver.update(updateUri, values, null, null);
    11     }

    查询

     1 //使用ContentProvider查询数据的测试
     2     public void testFind() throws Throwable {
     3         ContentResolver contentResolver = this.getContext().getContentResolver();
     4         //这个uri用于查询所有的数据,若查询某个id的数据,则构建下面的uri
     5         //Uri selectUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student/要查询的id");
     6         Uri selectUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student");
     7         Cursor cursor = contentResolver.query(selectUri, null, null, null, "id desc");
     8         while (cursor.moveToNext()) {
     9             int id = cursor.getInt(cursor.getColumnIndex("id"));
    10             String name = cursor.getString(cursor.getColumnIndex("name"));
    11             int age = cursor.getInt(cursor.getColumnIndex("age"));
    12             String school = cursor.getString(cursor.getColumnIndex("school"));
    13             Log.i(TAG, "id=" + id + ",name=" + name + ",age=" + age +",school="+school);
    14         }
    15     }

    上面的方法都经过了单元测试。
    好了,至此,我们就使用ContentProvider实现了在第三方应用中对我们应用的数据库进行增删改查等操作,如有疑问,请留言。

    转载自:http://www.it165.net/pro/html/201406/15166.html

  • 相关阅读:
    Python中如何调用Linux命令
    python入门小记
    DNS域名解析的过程
    阿里云Aliyun_server
    ipython及Python初体验
    js 的数值限制可能引起的问题
    页面图片中间有条线----解决
    ie6幽灵文字及解决办法
    解除工商银行15分钟限制
    ie6 无法显示网页 已终止操作
  • 原文地址:https://www.cnblogs.com/wanghaoyuhappy/p/5294037.html
Copyright © 2011-2022 走看看