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
<provider android:name=".StudentProvider" android:authorities="com.example.android_contentprovider.StudentProvider"> </provider>
主配置文件
定义了一个Tools工具类便于操作
package com.example.android_contentprovider; import android.net.Uri; public class Tools { public static final int VERSION = 1;// 数据库版本号 public static final String DNAME = "student.db";// 数据库名称 public static final String TABLE_NAME = "student";// 表名 public static final String ID="id"; public static final String PEOPLE_NAME="name"; public static final String ADDRESS="address"; public static final String SEX="sex"; public static final int STUDENT=1; public static final int STUDENTS=2; public static final String AUTHORITY="com.example.android_contentprovider.StudentProvider"; public static final String ONLY="vnd.android.cursor.item/"+TABLE_NAME; public static final String MULITY= "vnd.android.cursor.dir/"+TABLE_NAME; public static final String URL="content://"+AUTHORITY+"/"+TABLE_NAME; }
Tools.java
创建名为student的数据库
package com.example.android_contentprovider; import android.content.Context; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class DbHelper extends SQLiteOpenHelper { public DbHelper(Context context) { super(context, Tools.DNAME, null, Tools.VERSION); // TODO Auto-generated constructor stub } // 创建一个数据库 @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub String sql = "create table " + Tools.TABLE_NAME + " ( " + Tools.ID + " integer primary key autoincrement ," + Tools.PEOPLE_NAME + " varchar(64)," + Tools.ADDRESS + " varchar(64))"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } }
DbHelper.java
创建子类继承ContentProvider,进行配置。
package com.example.android_contentprovider; import android.R.integer; import android.R.string; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.CursorJoiner.Result; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.provider.ContactsContract.Contacts.Data; import android.provider.SyncStateContract.Helpers; import android.util.Log; public class StudentProvider extends ContentProvider { // 实例化 private DbHelper helper = null; public static final UriMatcher pUriMatcher = new UriMatcher( UriMatcher.NO_MATCH); static { pUriMatcher.addURI(Tools.AUTHORITY, Tools.TABLE_NAME + "/#", Tools.STUDENT); pUriMatcher.addURI(Tools.AUTHORITY, Tools.TABLE_NAME, Tools.STUDENTS); } @Override public boolean onCreate() { // TODO Auto-generated method stub helper = new DbHelper(getContext()); return false; } //进行查找操作 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub Cursor cursor = null; try { SQLiteDatabase database = helper.getWritableDatabase(); int flag = pUriMatcher.match(uri); switch (flag) { case Tools.STUDENT: long id = ContentUris.parseId(uri); String where_values = " id = " + id; if (selection != null && !selection.equals("")) { where_values += " and " + selection; } cursor = database.query(Tools.TABLE_NAME, null, where_values, selectionArgs, null, null, null); break; case Tools.STUDENTS: cursor = database.query(Tools.TABLE_NAME, null, selection, selectionArgs, null, null, null); break; } } catch (Exception e) { // TODO: handle exception } return cursor; } @Override public String getType(Uri uri) { // 得到匹配符 int flag = pUriMatcher.match(uri); switch (flag) { case Tools.STUDENT: return Tools.ONLY; case Tools.STUDENTS: return Tools.MULITY; default: throw new IllegalArgumentException("Unknown URI" + uri); } } // 进行插入操作 @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub Uri resultUri = null; int flag = pUriMatcher.match(uri); switch (flag) { case Tools.STUDENTS: SQLiteDatabase database = null; database = helper.getWritableDatabase(); // id表示插入当前行的行号 long id = database.insert(Tools.TABLE_NAME, null, values); resultUri = ContentUris.withAppendedId(uri, id); getContext().getContentResolver().notifyChange(resultUri, null); break; } Log.i("StudentProvider", resultUri.toString()); return resultUri; } // 进行删除操作 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int resultId = -; try { SQLiteDatabase database = helper.getWritableDatabase(); int flag = pUriMatcher.match(uri); switch (flag) { case Tools.STUDENT: long id = ContentUris.parseId(uri); String where_values = "id= " + resultId; if (selection != null && !selection.equals("")) { where_values += " and " + selection; } resultId = database.delete(Tools.TABLE_NAME, where_values, selectionArgs); break; case Tools.STUDENTS: resultId = database.delete(Tools.TABLE_NAME, selection, selectionArgs); break; } } catch (Exception e) { // TODO: handle exception } return resultId; } //进行修改更新 @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int resultId = -; try { // update table set name=?,address=? where id=? long id = ContentUris.parseId(uri); int flag = pUriMatcher.match(uri); SQLiteDatabase database = helper.getWritableDatabase(); switch (flag) { case Tools.STUDENT: String where_values = " id = " + id; if (selection != null && !selection.equals("")) { where_values += " and " + selection; } resultId = database.update(Tools.TABLE_NAME, values, where_values, selectionArgs); break; } } catch (Exception e) { // TODO: handle exception } return resultId; } }
StudentProvider.java
这里我注册了一个instrumentation单元测试。
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.example.android_contentprovider">
</instrumentation>
定义MyTest测试类继承AndroidTestCase
package com.example.android_contentprovider; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.test.AndroidTestCase; public class MyTest extends AndroidTestCase { public MyTest() { // TODO Auto-generated constructor stub } public void insert() { ContentResolver contentResolver = getContext().getContentResolver(); Uri url = Uri.parse(Tools.URL); ContentValues values = new ContentValues(); values.put(Tools.PEOPLE_NAME, "王五"); values.put(Tools.ADDRESS, "北京"); contentResolver.insert(url, values); } public void delete() { ContentResolver contentResolver = getContext().getContentResolver(); Uri uri = Uri.parse(Tools.URL + "/1"); contentResolver.delete(uri, null, null); } public void update() { ContentResolver contentResolver = getContext().getContentResolver(); Uri uri = Uri.parse(Tools.URL + "/2"); ContentValues values = new ContentValues(); values.put(Tools.PEOPLE_NAME, "程洋"); values.put(Tools.ADDRESS, "上海"); contentResolver.update(uri, values, null, null); } public void query() { ContentResolver contentResolver = getContext().getContentResolver(); Uri uri = Uri.parse(Tools.URL); Cursor cursor = contentResolver.query(uri, null, null, null, null); while (cursor.moveToNext()) { // 输出查询该条记录的名字 System.out .println("你所查找的学生为:" + cursor.getString(cursor .getColumnIndex(Tools.PEOPLE_NAME)) + ";地址为:" + cursor.getString(cursor .getColumnIndex(Tools.ADDRESS))); } } }
MyTest.java
note:正学习Android之中,不足的地方还有很多望见谅。