首先,ContentProvider(内容提供者)是android中的四大组件之一,可是在通常的开发中,可能使用的比较少。 ContentProvider为不一样的软件之间数据共享,提供统一的接口。也就是说,若是咱们想让其余的应用使用咱们本身程序内的数据,就可使用ContentProvider定义一个对外开放的接口,从而使得其余的应用可使用我们应用的文件、数据库内存储的信息。固然,本身开发的应用须要给其余应用共享信息的需求可能比较少见,可是在Android系统中,不少系统自带应用,好比联系人信息,图片库,音频库等应用,为了对其余应用暴露数据,因此就使用了ContentProvider机制。因此,咱们仍是要学习ContentProvider的基本使用,在遇到获取联系人信息,图片库,音频库等需求的时候,才能更好的实现功能html
Android系统为了让咱们更好的对外暴露数据,提供了统一的接口,因此定义了抽象类ContentProvider,所以,若是咱们想对外提供数据,咱们须要继承ContentProvider,而且实现下面的这几个方法:
onCreate() 当咱们的provider初始化时被调用,咱们应该在这个方法里面完成部分初始化操做 query() 查询方法,用于给调用者返回数据 insert() 插入操做,用于让外部应用插入数据到内容提供者中 update() 更新操做,用于更新内容提供者的数据 delete() 用于删除数据 getType 返回内容提供者的MIME Type
上面这些方法,当咱们继承自ContentProvider的时候,eclipse会自动的给咱们添加,可是这并不表明咱们每一个方法都须要自定义实现。若是咱们只但愿给其余应用提供数据,而不容许其余应用修改咱们的数据,那么咱们只须要实现onCreate(),getType()和query()这三个方法就能够了,其余的三个方法咱们能够根据业务需求,实现或者是不实现。
由于通常使用ContentProvider向外部暴露数据库的信息,所以,本篇将以使用ContentProvider向其余应用暴露数据库信息为例,讲解ContentProvider的基本使用。
Android中SQLite数据库的建立和使用,本篇再也不介绍,不清楚的请看这篇文章 SQLite数据库的简单实用android
假设读者已经学会了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的生命,其余的应用如今就可使用咱们往外部暴露的数据信息了。app
咱们已经定义好了咱们本身的ContentProvider,那么外部应用如何调用呢? 下面,我将新建一个测试单元工程,完成对ContentProvider的各个方法的测试
添加方法测试eclipse
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 }
删除方法测试ide
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