标签:
contentProvider:ContentProvider在Android中的作用是对外提供数据,除了可以为所在应用提供数据外,还可以共享数据给其他应用,这是Android中解决应用之间数据共享的机制。
通过ContentProvider我们可以对数据进行增删改查的操作。使用ContentProvider对外共享数据的好处是统一了数据的访问方式。
ContentProvider在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对你应用中的数据进行添删改查。
关于数据共享,以前我们学习过文件操作模式,知道通过指定文件的操作模式为Context.MODE_WORLD_READABLE或Context.MODE_WORLD_WRITEABLE同样也可以对外共享数据。
那么,这里为何要使用ContentProvider对外共享数据呢?
是这样的,如果采用文件操作模式对外共享数据,数据的访问方式会因数据存储的方式而不同,导致数据的访问方式无法统一,如:
采用xml文件对外共享数据,需要进行xml解析才能读取数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读取数据。
一般的数据库比如sqlitedatabase,是不能跨应用访问的,比如A.apk中的数据不能被B.apk使用,ContentProvider则可以跨平台访问数据。
默认的内容提供者方式应用有音视频、图片、通讯录、日历等。
示例:
第一步.首先在清单文件中添加单元测试授权和包
第二步.ContentProvider对外提供了完整的增删查改的操作,对内是通过数据库的操作实现的。
首先创建一个DBHelper类,让它继承SQLiteOpenHelper
1 package com.example.android_07contentprovider; 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 12 private static String name="mydb.db"; 13 private static int version=1; 14 public DBHelper(Context context) { 15 super(context, name, null, version); 16 // TODO Auto-generated constructor stub 17 } 18 @Override 19 public void onCreate(SQLiteDatabase db) { 20 // TODO Auto-generated method stub 21 String sql="create table student(id integer primary key autoincrement,name varchar(64),address varchar(64))"; 22 db.execSQL(sql);//对表的创建 23 } 24 25 @Override 26 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 27 // TODO Auto-generated method stub 28 29 } 30 31 }
第三步.定义一个内容提供者studentProvider 继承ContentProvider。
并在清单文件中进行注册,在注册ContentProvider时,采用了authorities(主机名/域名)的方法对它进行唯一标识,
ContentProvider的标识类似于网站的域名,通过此域名我们可以准确访问到对应网站,网站为我们提供数据。
Authorities就是ContentProvider的域名。注册方法如下:
1 <provider android:name=".studentProvider" android:authorities="com.example.android_07contentprovider.studentProvider"></provider>
0.在create方法中实例化一个DBhelper对象:helper=new DBHelper(getContext());
1.在内容提供者内部声明一个UriMatcher对象,用来与内容解析者发送的地址进行匹配判断
2.声明标识位,用来判断操作单条还是多条记录
3.声明静态代码模块,用来定义匹配规则 *用来匹配所有的文字,#用来匹配所有的数字
matcher.addURI("授权地址", "一般设置成表名", 标志位);
1 static{ 2 /**静态代码块定义匹配规则 3 * 清单文件中注册的授权地址 4 * 路径 通常设置为表名 5 */ 6 matcher.addURI("com.example.android_07contentprovider.studentProvider", "student/#", STUDENT); 7 matcher.addURI("com.example.android_07contentprovider.studentProvider", "student", STUDENTS); 8 }
4.重写getType()方法,处理头部类型,来判断操作单条还是多条记录
1 public String getType(Uri uri) { 2 // TODO Auto-generated method stub 3 int flag=matcher.match(uri); 4 switch (flag) { 5 case STUDENT: 6 return "vnd.android.cursor.item/student"; 7 case STUDENTS: 8 return "vnd.android.cursor.dir/students"; 9 } 10 return null; 11 }
5.重写插入方法,返回uri供其他应用使用
1 @Override 2 public Uri insert(Uri uri, ContentValues values) { 3 // TODO Auto-generated method stub 4 Uri resUri=null; 5 int flag=matcher.match(uri);//uri参数是外部传递过来的规则 与提供者的规则进行匹配 6 switch (flag) { 7 case STUDENTS: 8 SQLiteDatabase db=helper.getWritableDatabase(); 9 long id=db.insert("student", null, values);//返回id为插入当前行的行号 10 resUri=ContentUris.withAppendedId(uri, id); 11 break; 12 } 13 Log.i(TAG, "---->>"+resUri.toString()); 14 return resUri;//content//返回给其他应用使用 15 }
6.测试:
a.需要定义一个内容解析者:ContentResolver resolver=getContext().getContentResolver();
b.调用内容解析者的insert方法:resolver.insert(uri, values);
c得到uri 和contentValues
最终源码:
项目结构:
MainActivity无变化
DBHelper工具类:
1 package com.example.android_07contentprovider; 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 12 private static String name="mydb.db"; 13 private static int version=1; 14 public DBHelper(Context context) { 15 super(context, name, null, version); 16 // TODO Auto-generated constructor stub 17 } 18 @Override 19 public void onCreate(SQLiteDatabase db) { 20 // TODO Auto-generated method stub 21 String sql="create table student(id integer primary key autoincrement,name varchar(64),address varchar(64))"; 22 db.execSQL(sql);//对表的创建 23 } 24 25 @Override 26 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 27 // TODO Auto-generated method stub 28 29 } 30 31 }
studentProvider:
1 package com.example.android_07contentprovider; 2 3 import android.content.ContentProvider; 4 import android.content.ContentUris; 5 import android.content.ContentValues; 6 import android.content.UriMatcher; 7 import android.database.Cursor; 8 import android.database.sqlite.SQLiteDatabase; 9 import android.net.Uri; 10 import android.util.Log; 11 12 public class studentProvider extends ContentProvider { 13 14 private static final String TAG="studentProvider"; 15 16 private DBHelper helper=null; 17 18 19 private static final UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH); 20 //标志位 分别表明操作单条、多条记录 21 private static final int STUDENT=1; 22 private static final int STUDENTS=2; 23 static{ 24 /**静态代码块定义匹配规则 25 * 清单文件中注册的授权地址 26 * 路径 通常设置为表名 27 */ 28 matcher.addURI("com.example.android_07contentprovider.studentProvider", "student/#", STUDENT); 29 matcher.addURI("com.example.android_07contentprovider.studentProvider", "student", STUDENTS); 30 } 31 public studentProvider() { 32 // TODO Auto-generated constructor stub 33 } 34 35 @Override 36 public boolean onCreate() { 37 // TODO Auto-generated method stub 38 helper=new DBHelper(getContext()); 39 return false; 40 } 41 42 @Override 43 public Cursor query(Uri uri, String[] projection, String selection, 44 String[] selectionArgs, String sortOrder) { 45 // TODO Auto-generated method stub 46 Cursor cursor=null; 47 try { 48 int flag=matcher.match(uri);//uri参数是外部传递过来的规则 与提供者的规则进行匹配 49 SQLiteDatabase db=helper.getReadableDatabase(); 50 switch (flag) { 51 case STUDENT: 52 //delete from student where id=? id是通过客户端传递过来的 需要进行截取 53 long id=ContentUris.parseId(uri); 54 String where_value="id="+id; 55 if(selection!=null&&!selection.equals("")){ 56 where_value+="and"+selection; 57 } 58 cursor=db.query("student", null, where_value, selectionArgs, null, null, null, null); 59 break; 60 case STUDENTS: 61 cursor=db.query("student", null, null, selectionArgs, null, null, null, null); 62 break; 63 } 64 65 } catch (Exception e) { 66 // TODO: handle exception 67 } 68 return cursor; 69 } 70 71 /** 72 * 73 */ 74 @Override 75 public String getType(Uri uri) { 76 // TODO Auto-generated method stub 77 int flag=matcher.match(uri); 78 switch (flag) { 79 case STUDENT: 80 return "vnd.android.cursor.item/student"; 81 case STUDENTS: 82 return "vnd.android.cursor.dir/students"; 83 } 84 return null; 85 } 86 87 @Override 88 public Uri insert(Uri uri, ContentValues values) { 89 // TODO Auto-generated method stub 90 Uri resUri=null; 91 int flag=matcher.match(uri);//uri参数是外部传递过来的规则 与提供者的规则进行匹配 92 switch (flag) { 93 case STUDENTS: 94 SQLiteDatabase db=helper.getWritableDatabase(); 95 long id=db.insert("student", null, values);//返回id为插入当前行的行号 96 resUri=ContentUris.withAppendedId(uri, id); 97 break; 98 } 99 Log.i(TAG, "---->>"+resUri.toString()); 100 return resUri;//content//返回给其他应用使用 101 } 102 103 @Override 104 public int delete(Uri uri, String selection, String[] selectionArgs) { 105 // TODO Auto-generated method stub 106 int count=-1;//表示影响数据库的行数 107 try { 108 int flag=matcher.match(uri);//uri参数是外部传递过来的规则 与提供者的规则进行匹配 109 SQLiteDatabase db=helper.getWritableDatabase(); 110 switch (flag) { 111 case STUDENT: 112 //delete from student where id=? id是通过客户端传递过来的 需要进行截取 113 long id=ContentUris.parseId(uri); 114 String where_value="id="+id; 115 if(selection!=null&&!selection.equals("")){ 116 where_value+="and"+selection; 117 } 118 count=db.delete("student", where_value, selectionArgs); 119 break; 120 case STUDENTS: 121 count=db.delete("student", selection, selectionArgs); 122 break; 123 } 124 125 } catch (Exception e) { 126 // TODO: handle exception 127 } 128 return count; 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 count=-1;//表示影响数据库的行数 136 try { 137 //update student set name=?,address=? where id=? 138 int flag=matcher.match(uri);//uri参数是外部传递过来的规则 与提供者的规则进行匹配 139 SQLiteDatabase db=helper.getWritableDatabase(); 140 switch (flag) { 141 case STUDENT: 142 //delete from student where id=? id是通过客户端传递过来的 需要进行截取 143 long id=ContentUris.parseId(uri); 144 String where_value="id="+id; 145 if(selection!=null&&!selection.equals("")){ 146 where_value+="and"+selection; 147 } 148 count=db.update("student", values,where_value, selectionArgs); 149 break; 150 } 151 152 } catch (Exception e) { 153 // TODO: handle exception 154 } 155 return count; 156 } 157 158 }
测试类(内容解析者)
1 package com.example.android_07contentprovider; 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 public void insert(){ 15 //访问内容提供者的步骤 16 //1.需要一个内容解析者 17 ContentResolver resolver=getContext().getContentResolver(); 18 //2.content://+授权 +表名来访问内容提供者 19 Uri uri=Uri.parse("content://com.example.android_07contentprovider.studentProvider/student"); 20 ContentValues values=new ContentValues(); 21 values.put("name", "zhangsan"); 22 values.put("address", "zhogngguo"); 23 resolver.insert(uri, values); 24 } 25 public void delete(){ 26 ContentResolver resolver=getContext().getContentResolver(); 27 //单条删除 28 /*Uri uri=Uri.parse("content://com.example.android_07contentprovider.studentProvider/student/1"); 29 resolver.delete(uri, null,null);*/ 30 //多条删除 31 Uri uri=Uri.parse("content://com.example.android_07contentprovider.studentProvider/student"); 32 resolver.delete(uri, null,null); 33 } 34 public void modify(){ 35 ContentResolver resolver=getContext().getContentResolver(); 36 Uri uri=Uri.parse("content://com.example.android_07contentprovider.studentProvider/student/4"); 37 ContentValues values=new ContentValues(); 38 values.put("name", "zhaohaohao"); 39 values.put("address", "jiaozuo"); 40 resolver.update(uri, values, null, null); 41 } 42 public void query(){ 43 ContentResolver resolver=getContext().getContentResolver(); 44 //查询单条记录 45 Uri uri=Uri.parse("content://com.example.android_07contentprovider.studentProvider/student/5"); 46 Cursor cursor=resolver.query(uri, null, null, null, null); 47 while(cursor.moveToNext()){ 48 System.out.println(cursor.getString(cursor.getColumnIndex("name"))); 49 } 50 //查询多条记录 51 /*Uri uri=Uri.parse("content://com.example.android_07contentprovider.studentProvider/student"); 52 Cursor cursor=resolver.query(uri, null, null, null, null); 53 while(cursor.moveToNext()){ 54 System.out.println(cursor.getString(cursor.getColumnIndex("name"))); 55 }*/ 56 } 57 }
标签:
原文地址:http://www.cnblogs.com/mlj5288/p/4963339.html