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 }
Tools.java
创建名为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 stub 14 } 15 16 // 创建一个数据库 17 18 @Override 19 public void onCreate(SQLiteDatabase db) { 20 // TODO Auto-generated method stub 21 String sql = "create table " + Tools.TABLE_NAME + " ( " + Tools.ID 22 + " integer primary key autoincrement ," + Tools.PEOPLE_NAME 23 + " varchar(64)," + Tools.ADDRESS + " varchar(64))"; 24 db.execSQL(sql); 25 } 26 27 @Override 28 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 29 // TODO Auto-generated method stub 30 31 } 32 33 }
DbHelper.java
创建子类继承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 @Override 102 public int delete(Uri uri, String selection, String[] selectionArgs) { 103 // TODO Auto-generated method stub 104 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 exception 126 } 127 128 return resultId; 129 } 130 //进行修改更新 131 @Override 132 public int update(Uri uri, ContentValues values, String selection, 133 String[] selectionArgs) { 134 // TODO Auto-generated method stub 135 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 exception 153 } 154 return resultId; 155 } 156 157 }
StudentProvider.java
这里我注册了一个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 stub 13 } 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.out 47 .println("你所查找的学生为:" 48 + cursor.getString(cursor 49 .getColumnIndex(Tools.PEOPLE_NAME)) 50 + ";地址为:" 51 + cursor.getString(cursor 52 .getColumnIndex(Tools.ADDRESS))); 53 } 54 } 55 }
MyTest.java
note:正学习Android之中,不足的地方还有很多望见谅。