码迷,mamicode.com
首页 > 移动开发 > 详细

Android 之contentProvider

时间:2015-11-14 11:07:32      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:

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 }
View Code

第三步.定义一个内容提供者studentProvider 继承ContentProvider。

并在清单文件中进行注册,在注册ContentProvider时,采用了authorities(主机名/域名)的方法对它进行唯一标识,

ContentProvider的标识类似于网站的域名,通过此域名我们可以准确访问到对应网站,网站为我们提供数据。

Authorities就是ContentProvider的域名。注册方法如下:

技术分享
1  <provider android:name=".studentProvider" android:authorities="com.example.android_07contentprovider.studentProvider"></provider>
View Code

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     }
View Code

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     }
View Code

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     }
View Code

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 }
View Code

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 }
View Code

测试类(内容解析者)

技术分享
 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 }
View Code

 

Android 之contentProvider

标签:

原文地址:http://www.cnblogs.com/mlj5288/p/4963339.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!