Android中的四大组件之一ContentProvider,它支持多个应用间进行存储和读取数据等操作,实现不同应用间的数据共享。
ContentProvider,解释为内容提供商。顾名思义,就是对外提供数据。其工作形式主要是ContentProvider以Uri的形式对外提供数据,允许其他应用访问或者修改数据,其他应用程序就使用ContentResolver根据ContentProvider提供的Uri去访问进行对数据的各种操作。
实现数据共享的步骤:
1,创建一个简单的数据库供ContentProvider进行操作。创建数据库方法:定义子类继承SQLiteOpenHelper,在onCreate()方法中申明SQL创建语句,用execSQL()创建。
2,定义一个子类继承ContentProvider,然后在主配置文件中对你申明的ContentProvider进行注册!必须要注册!
3,重写其中的各种方法,如getType(),insert(),delete(),update(),query()方法。,
在其子类中,我们要做的很重要的一件事就是进行Uri的配置,使其他应用可以通过ContentResolver根据其Uri进行操作。这里我们就要用到UriMatcher类,它主要有两个方法:
一个是addURI(String authority, String path, int code),它要做的就是添加Uri。authority表示其主配置文件中的注册授权,path表示要进行操作的表名,code是你自己定义的整数。
另一个是match(Uri uri),uri就是你所要操作的uri地址,它返回一个整数,就是你之前自己定义的code。
这两个方法就相当与加密和解码的功能。一个Uri就代表对特定数据的操作。
在进行解析Uri的时候,我们需要对Uri结尾处的数字(即你所要操作表的行的id),这时候就要用到ContentUris,它用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
一个是 withAppendedId(uri, id)用于为路径加上ID部分
另一个是parseId(uri)方法用于从路径中获取ID部分
4,通过Context的getContentResolver()方法实例化ContentResolver。根据ContentProvider所提供的Uri进行数据访问和操作。
以下是我的操作代码:
主配置文件注册ContentProvider
1 <provider android:name=".StudentProvider"2 android:authorities="com.example.android_contentprovider.StudentProvider">3 </provider>
定义了一个Tools工具类便于操作
1 package com.example.android_contentprovider; 2 3 import android.net.Uri; 4 5 public class Tools { 6 7 public static final int VERSION = 1;// 数据库版本号 8 public static final String DNAME = "student.db";// 数据库名称 9 public static final String TABLE_NAME = "student";// 表名10 public static final String ID="id";11 public static final String PEOPLE_NAME="name";12 public static final String ADDRESS="address";13 public static final String SEX="sex";14 public static final int STUDENT=1;15 public static final int STUDENTS=2;16 public static final String AUTHORITY="com.example.android_contentprovider.StudentProvider";17 public static final String ONLY="vnd.android.cursor.item/"+TABLE_NAME;18 public static final String MULITY= "vnd.android.cursor.dir/"+TABLE_NAME;19 public static final String URL="content://"+AUTHORITY+"/"+TABLE_NAME;20 }
创建名为student的数据库
1 package com.example.android_contentprovider; 2 3 import android.content.Context; 4 import android.database.DatabaseErrorHandler; 5 import android.database.sqlite.SQLiteDatabase; 6 import android.database.sqlite.SQLiteDatabase.CursorFactory; 7 import android.database.sqlite.SQLiteOpenHelper; 8 9 public class DbHelper extends SQLiteOpenHelper {10 11 public DbHelper(Context context) {12 super(context, Tools.DNAME, null, Tools.VERSION);13 // TODO Auto-generated constructor stub14 }15 16 // 创建一个数据库17 18 @Override19 public void onCreate(SQLiteDatabase db) {20 // TODO Auto-generated method stub21 String sql = "create table " + Tools.TABLE_NAME + " ( " + Tools.ID22 + " integer primary key autoincrement ," + Tools.PEOPLE_NAME23 + " varchar(64)," + Tools.ADDRESS + " varchar(64))";24 db.execSQL(sql);25 }26 27 @Override28 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {29 // TODO Auto-generated method stub30 31 }32 33 }
创建子类继承ContentProvider,进行配置。
1 package com.example.android_contentprovider; 2 3 import android.R.integer; 4 import android.R.string; 5 import android.content.ContentProvider; 6 import android.content.ContentUris; 7 import android.content.ContentValues; 8 import android.content.UriMatcher; 9 import android.database.Cursor; 10 import android.database.CursorJoiner.Result; 11 import android.database.sqlite.SQLiteDatabase; 12 import android.net.Uri; 13 import android.provider.ContactsContract.Contacts.Data; 14 import android.provider.SyncStateContract.Helpers; 15 import android.util.Log; 16 17 public class StudentProvider extends ContentProvider { 18 // 实例化 19 private DbHelper helper = null; 20 public static final UriMatcher pUriMatcher = new UriMatcher( 21 UriMatcher.NO_MATCH); 22 static { 23 pUriMatcher.addURI(Tools.AUTHORITY, Tools.TABLE_NAME + "/#", 24 Tools.STUDENT); 25 pUriMatcher.addURI(Tools.AUTHORITY, Tools.TABLE_NAME, Tools.STUDENTS); 26 } 27 28 @Override 29 public boolean onCreate() { 30 // TODO Auto-generated method stub 31 helper = new DbHelper(getContext()); 32 return false; 33 } 34 //进行查找操作 35 @Override 36 public Cursor query(Uri uri, String[] projection, String selection, 37 String[] selectionArgs, String sortOrder) { 38 // TODO Auto-generated method stub 39 Cursor cursor = null; 40 try { 41 SQLiteDatabase database = helper.getWritableDatabase(); 42 int flag = pUriMatcher.match(uri); 43 switch (flag) { 44 case Tools.STUDENT: 45 long id = ContentUris.parseId(uri); 46 String where_values = " id = " + id; 47 48 if (selection != null && !selection.equals("")) { 49 where_values += " and " + selection; 50 } 51 cursor = database.query(Tools.TABLE_NAME, null, where_values, 52 selectionArgs, null, null, null); 53 break; 54 case Tools.STUDENTS: 55 cursor = database.query(Tools.TABLE_NAME, null, selection, 56 selectionArgs, null, null, null); 57 break; 58 } 59 } catch (Exception e) { 60 // TODO: handle exception 61 } 62 return cursor; 63 } 64 65 @Override 66 public String getType(Uri uri) { 67 // 得到匹配符 68 int flag = pUriMatcher.match(uri); 69 switch (flag) { 70 case Tools.STUDENT: 71 return Tools.ONLY; 72 case Tools.STUDENTS: 73 return Tools.MULITY; 74 default: 75 throw new IllegalArgumentException("Unknown URI" + uri); 76 } 77 } 78 79 // 进行插入操作 80 @Override 81 public Uri insert(Uri uri, ContentValues values) { 82 // TODO Auto-generated method stub 83 Uri resultUri = null; 84 int flag = pUriMatcher.match(uri); 85 switch (flag) { 86 case Tools.STUDENTS: 87 SQLiteDatabase database = null; 88 database = helper.getWritableDatabase(); 89 // id表示插入当前行的行号 90 long id = database.insert(Tools.TABLE_NAME, null, values); 91 resultUri = ContentUris.withAppendedId(uri, id); 92 getContext().getContentResolver().notifyChange(resultUri, null); 93 break; 94 95 } 96 Log.i("StudentProvider", resultUri.toString()); 97 return resultUri; 98 } 99 100 // 进行删除操作101 @Override102 public int delete(Uri uri, String selection, String[] selectionArgs) {103 // TODO Auto-generated method stub104 int resultId = -1;105 try {106 SQLiteDatabase database = helper.getWritableDatabase();107 int flag = pUriMatcher.match(uri);108 switch (flag) {109 case Tools.STUDENT:110 long id = ContentUris.parseId(uri);111 String where_values = "id= " + resultId;112 if (selection != null && !selection.equals("")) {113 where_values += " and " + selection;114 }115 resultId = database.delete(Tools.TABLE_NAME, where_values,116 selectionArgs);117 118 break;119 case Tools.STUDENTS:120 resultId = database.delete(Tools.TABLE_NAME, selection,121 selectionArgs);122 break;123 }124 } catch (Exception e) {125 // TODO: handle exception126 }127 128 return resultId;129 }130 //进行修改更新131 @Override132 public int update(Uri uri, ContentValues values, String selection,133 String[] selectionArgs) {134 // TODO Auto-generated method stub135 int resultId = -1;136 try {137 // update table set name=?,address=? where id=?138 long id = ContentUris.parseId(uri);139 int flag = pUriMatcher.match(uri);140 SQLiteDatabase database = helper.getWritableDatabase();141 switch (flag) {142 case Tools.STUDENT:143 String where_values = " id = " + id;144 if (selection != null && !selection.equals("")) {145 where_values += " and " + selection;146 }147 resultId = database.update(Tools.TABLE_NAME, values,148 where_values, selectionArgs);149 break;150 }151 } catch (Exception e) {152 // TODO: handle exception153 }154 return resultId;155 }156 157 }
这里我注册了一个instrumentation单元测试。
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.example.android_contentprovider">
</instrumentation>
定义MyTest测试类继承AndroidTestCase
1 package com.example.android_contentprovider; 2 3 import android.content.ContentResolver; 4 import android.content.ContentValues; 5 import android.database.Cursor; 6 import android.net.Uri; 7 import android.test.AndroidTestCase; 8 9 public class MyTest extends AndroidTestCase {10 11 public MyTest() {12 // TODO Auto-generated constructor stub13 }14 15 public void insert() {16 ContentResolver contentResolver = getContext().getContentResolver();17 Uri url = Uri.parse(Tools.URL);18 ContentValues values = new ContentValues();19 values.put(Tools.PEOPLE_NAME, "王五");20 values.put(Tools.ADDRESS, "北京");21 contentResolver.insert(url, values);22 }23 24 public void delete() {25 ContentResolver contentResolver = getContext().getContentResolver();26 Uri uri = Uri.parse(Tools.URL + "/1");27 contentResolver.delete(uri, null, null);28 }29 30 public void update() {31 ContentResolver contentResolver = getContext().getContentResolver();32 Uri uri = Uri.parse(Tools.URL + "/2");33 ContentValues values = new ContentValues();34 values.put(Tools.PEOPLE_NAME, "程洋");35 values.put(Tools.ADDRESS, "上海");36 contentResolver.update(uri, values, null, null);37 38 }39 40 public void query() {41 ContentResolver contentResolver = getContext().getContentResolver();42 Uri uri = Uri.parse(Tools.URL);43 Cursor cursor = contentResolver.query(uri, null, null, null, null);44 while (cursor.moveToNext()) {45 // 输出查询该条记录的名字46 System.out47 .println("你所查找的学生为:"48 + cursor.getString(cursor49 .getColumnIndex(Tools.PEOPLE_NAME))50 + ";地址为:"51 + cursor.getString(cursor52 .getColumnIndex(Tools.ADDRESS)));53 }54 }55 }
note:正学习Android之中,不足的地方还有很多望见谅。