android contentprovider的使用(二)

来源:互联网 发布:linux jar 解压 编辑:程序博客网 时间:2024/06/05 20:56

使用ContentProvider共享数据

当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。

当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法:

public class PersonContentProvider extends ContentProvider{

   public boolean onCreate()

   public Uri insert(Uri uri, ContentValues values)

   public int delete(Uri uri, String selection, String[] selectionArgs)

   public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

   public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

   public String getType(Uri uri)}

第二步需要在AndroidManifest.xml使用<provider>对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider , ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:

<manifest .... >

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <provider android:name=".PersonContentProvider" android:authorities="com.jbridge.provider.personprovider"/>

    </application>

</manifest>

注意:一旦应用继承了ContentProvider类,后面我们就会把这个应用称为ContentProvider(内容提供者)。

Uri介绍

Uri代表了要操作的数据,Uri主要包含了两部分信息:1》需要操作的ContentProvider ,2》对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:



 ContentProvider(内容提供者)的scheme已经由Android所规定, scheme为:content://
主机名(或叫Authority)用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
要操作person表中id为10的记录,可以构建这样的路径:/person/10
要操作person表中id为10的记录的name字段, person/10/name
要操作person表中的所有记录,可以构建这样的路径:/person
要操作xxx表中的记录,可以构建这样的路径:/xxx
当然要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://com.jbridge.provider.personprovider/person")
UriMatcher类使用介绍
因为Uri代表了要操作的数据,所以我们很经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的开发工作。
UriMatcher类用于匹配Uri,它的用法如下:
首先第一步把你需要匹配Uri路径全部给注册上,如下:
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(UriMatcher.NO_MATCH的值为-1)
UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//如果match()方法匹配content://com.jbridge.provider.personprovider/person路径,返回匹配码为1
sMatcher.addURI(“com.jbridge.provider.personprovider”, “person”, 1);//添加需要匹配uri,如果匹配就会返回匹配码
//如果match()方法匹配content://com.jbridge.provider.personprovider/person/230路径,返回匹配码为2
sMatcher.addURI(“com.jbridge.provider.personprovider”, “person/#”, 2);//#号为通配符
switch (sMatcher.match(Uri.parse("content://com.jbridge.provider.personprovider/person/10"))) { 
   case 1
    break;
   case 2
    break;
   default://不匹配
    break;
}
注册完需要匹配的Uri后,就可以使用sMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,假设匹配content://com.jbridge.provider.personprovider/person路径,返回的匹配码为1
ContentUris类使用介绍
ContentUris类用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
withAppendedId(uri, id)用于为路径加上ID部分:
Uri uri = Uri.parse("content://com.jbridge.provider.personprovider/person")
Uri resultUri = ContentUris.withAppendedId(uri, 10); 
//生成后的Uri为:content://com.jbridge.provider.personprovider/person/10

parseId(uri)方法用于从路径中获取ID部分:
Uri uri = Uri.parse("content://com.jbridge.provider.personprovider/person/10")
long personid = ContentUris.parseId(uri);//获取的结果为:10
使用ContentProvider共享数据
ContentProvider类主要方法的作用:
public boolean onCreate()
该方法在ContentProvider创建后就会被调用, Android在系统启动时就会创建ContentProvider 。
public Uri insert(Uri uri, ContentValues values)
该方法用于供外部应用往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于供外部应用从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于供外部应用更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于供外部应用从ContentProvider中获取数据。
public String getType(Uri uri)
该方法用于返回当前Url所代表数据的MIME类型。如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,例如:要得到所有person记录的Uri为content://com.jbridge.provider.personprovider/person,那么返回的MIME类型字符串应该为:“vnd.android.cursor.dir/person”。如果要操作的数据属于单一数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:得到id为10的person记录,Uri为content://com.jbridge.provider.personprovider/person/10,那么返回的MIME类型字符串应该为:“vnd.android.cursor.item/person”。
使用ContentResolver操作ContentProvider中的数据
当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中获取数据。

这些方法的第一个参数为Uri,代表要操作的是哪个ContentProvider和对其中的什么数据进行操作,假设给定的是: Uri.parse(“content://com.jbridge.provider.personprovider/person/10”),那么将会对主机名为cn.itcast.provider.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。
使用ContentResolver操作ContentProvider中的数据
使用ContentResolver对ContentProvider中的数据进行添加、删除、修改和查询操作:
ContentResolver resolver =  getContentResolver();
Uri uri = Uri.parse("content://com.jbridge.provider.personprovider/person");
//添加一条记录
ContentValues values = new ContentValues();
values.put("name", "itcast");
values.put("age", 25);
resolver.insert(uri, values);
//获取person表中所有记录
Cursor cursor = resolver.query(uri, null, null, null, "personid desc");
while(cursor.moveToNext()){
Log.i("ContentTest", "personid="+ cursor.getInt(0)+ ",name="+ cursor.getString(1));
}
//把id为1的记录的name字段值更改新为liming
ContentValues updateValues = new ContentValues();
updateValues.put("name", "liming");
Uri updateIdUri = ContentUris.withAppendedId(uri, 2);
resolver.update(updateIdUri, updateValues, null, null);
//删除id为2的记录
Uri deleteIdUri = ContentUris.withAppendedId(uri, 2);
resolver.delete(deleteIdUri, null, null);

ContentProvider示例程序

 我们为《Android之SQlite存储》示例程序添加一个ContentProvider,供其他应用来访问我们的数据。

 

 1.为SQLite示例程序添加ContentProvider类

Java代码  收藏代码
  1. package com.jbridge.db;  
  2.   
  3. import com.jbridge.service.DataBaseOpenHelper;  
  4.   
  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.sqlite.SQLiteDatabase;  
  11. import android.net.Uri;  
  12. import android.text.TextUtils;  
  13.   
  14. public class PersonContentProvider extends ContentProvider {  
  15.     private DataBaseOpenHelper dbOpenHelper;  
  16.     private static final int ALLPERSON = 1;  
  17.     private static final int PERSON = 2;  
  18.     private static final UriMatcher sMatcher = new UriMatcher(  
  19.             UriMatcher.NO_MATCH);  
  20.     static {  
  21.         sMatcher.addURI("com.jbridge.provider.personprovider""person",  
  22.                 ALLPERSON);  
  23.         sMatcher.addURI("com.jbridge.provider.personprovider""person/#",  
  24.                 PERSON);  
  25.     }  
  26.   
  27.     @Override  
  28.     public int delete(Uri uri, String selection, String[] selectionArgs) {  
  29.         SQLiteDatabase db = dbOpenHelper.getWritableDatabase();  
  30.         int count = 0;  
  31.         switch (sMatcher.match(uri)) {  
  32.         case ALLPERSON:// com.jbridge.provider.personprovider/person  
  33.             count=db.delete("person", selection,selectionArgs);  
  34.             break;  
  35.         case PERSON:// com.jbridge.provider.personprovider/person/10  
  36.             long personid=ContentUris.parseId(uri);  
  37.             //防止他输入时String selection, String[] selectionArgs参数为空,这样就会修改表的所有数据了  
  38.             String where=TextUtils.isEmpty(selection)?"personid=?":selection+" and personid=?";  
  39.             String[] params=new String[]{String.valueOf(personid)};   
  40.             if (!TextUtils.isEmpty(selection)&&selectionArgs!=null) {  
  41.                 params=new String[selectionArgs.length+1];  
  42.                 for (int i=0;i<selectionArgs.length;i++) {  
  43.                     params[i]=selectionArgs[i];  
  44.                 }  
  45.                 params[selectionArgs.length]=String.valueOf(personid);  
  46.             }  
  47.             count = db.delete("person", where,params);  
  48.             break;  
  49.         default:  
  50.             throw new IllegalArgumentException("Unknow Uri:" + uri);  
  51.   
  52.         }  
  53.           
  54.         return count;  
  55.     }  
  56.   
  57.     @Override  
  58.     public String getType(Uri uri) {  
  59.         switch (sMatcher.match(uri)) {  
  60.         case ALLPERSON:// //数据集的MIME类型字符串则应该以vnd.android.cursor.dir/开头  
  61.             return "vnd.android.cursor.dir/personprovider.person";  
  62.         case PERSON://单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头  
  63.             return "vnd.android.cursor.item/personprovider.person";  
  64.         default:  
  65.             throw new IllegalArgumentException("Unknow Uri:" + uri);  
  66.         }  
  67.     }  
  68.   
  69.     @Override  
  70.     public Uri insert(Uri uri, ContentValues values) {  
  71.         SQLiteDatabase db = dbOpenHelper.getWritableDatabase();  
  72.         long id = 0;  
  73.         switch (sMatcher.match(uri)) {  
  74.         case ALLPERSON:// com.jbridge.provider.personprovider/person  
  75.             id = db.insert("person""name", values);// 返回值是记录的行号,主键为int实际上就是主键值,主键为text则为行号  
  76.             return ContentUris.withAppendedId(uri, id);  
  77.         case PERSON:// com.jbridge.provider.personprovider/person/10  
  78.             id = db.insert("person""name", values);// 返回值是记录的行号,主键为int实际上就是主键值,主键为text则为行号  
  79.             String path = uri.toString();  
  80.             return Uri.parse(path.substring(0, path.lastIndexOf("/")) + id);  
  81.         default:  
  82.             throw new IllegalArgumentException("Unknow Uri:" + uri);  
  83.         }  
  84.     }  
  85.   
  86.     @Override  
  87.     public boolean onCreate() {  
  88.         dbOpenHelper=new DataBaseOpenHelper(this.getContext());  
  89.         return false;  
  90.     }  
  91.   
  92.     @Override  
  93.     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,  
  94.             String sortOrder) {  
  95.         SQLiteDatabase db = dbOpenHelper.getWritableDatabase();  
  96.         switch (sMatcher.match(uri)) {  
  97.         case ALLPERSON:// com.jbridge.provider.personprovider/person  
  98.             return db.query("person",projection, selection, selectionArgs,nullnull, sortOrder);  
  99.         case PERSON:// com.jbridge.provider.personprovider/person/10  
  100.             long personid=ContentUris.parseId(uri);  
  101.             //防止他输入时String selection, String[] selectionArgs参数为空,这样就会修改表的所有数据了  
  102.             String where=TextUtils.isEmpty(selection)?"personid=?":selection+" and personid=?";  
  103.             String[] params=new String[]{String.valueOf(personid)};   
  104.             if (!TextUtils.isEmpty(selection)&&selectionArgs!=null) {  
  105.                 params=new String[selectionArgs.length+1];  
  106.                 for (int i=0;i<selectionArgs.length;i++) {  
  107.                     params[i]=selectionArgs[i];  
  108.                 }  
  109.                 params[selectionArgs.length]=String.valueOf(personid);  
  110.             }  
  111.             return db.query("person",projection, where, params,nullnull, sortOrder);  
  112.   
  113.         default:  
  114.             throw new IllegalArgumentException("Unknow Uri:" + uri);  
  115.   
  116.         }  
  117.           
  118.           
  119.     }  
  120.   
  121.     @Override  
  122.     //返回值为影响的记录数  
  123.     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {  
  124.         SQLiteDatabase db = dbOpenHelper.getWritableDatabase();  
  125.         int count = 0;  
  126.         switch (sMatcher.match(uri)) {  
  127.         case ALLPERSON:// com.jbridge.provider.personprovider/person  
  128.             count = db.update("person", values, selection,selectionArgs);  
  129.             break;  
  130.         case PERSON:// com.jbridge.provider.personprovider/person/10  
  131.             long personid=ContentUris.parseId(uri);  
  132.             //防止他输入时String selection, String[] selectionArgs参数为空,这样就会修改表的所有数据了  
  133.             String where=TextUtils.isEmpty(selection)?"personid=?":selection+" and personid=?";  
  134.             String[] params=new String[]{String.valueOf(personid)};   
  135.             if (!TextUtils.isEmpty(selection)&&selectionArgs!=null) {  
  136.                 params=new String[selectionArgs.length+1];  
  137.                 for (int i=0;i<selectionArgs.length;i++) {  
  138.                     params[i]=selectionArgs[i];  
  139.                 }  
  140.                 params[selectionArgs.length]=String.valueOf(personid);  
  141.             }  
  142.             count = db.update("person", values, where,params);  
  143.             break;  
  144.         default:  
  145.             throw new IllegalArgumentException("Unknow Uri:" + uri);  
  146.   
  147.         }  
  148.           
  149.         return count;  
  150.     }  
  151.   
  152. }  
 

       2.添加ContentProvider配置

 <provider android:name=".PersonContentProvider" android:authorities="com.jbridge.provider.personprovider"  android:permission="android.permission.READ_PERSON_DB"/>   

       3.测试SQLite示例程序的ContentProvider,建立项目contentProviderUser

 

       Project name: contentProviderUser

       BuildTarget:Android2.2

       Application name: 内容使用者

       Package name: com.jbridge.user

       Create Activity: ContentProviderUserActivity

       Min SDK Version:8

 

     

Java代码  收藏代码
  1. package com.jbridge.user;  
  2.   
  3. import android.R.string;  
  4. import android.app.Activity;  
  5. import android.content.ContentResolver;  
  6. import android.content.ContentValues;  
  7. import android.database.Cursor;  
  8. import android.net.Uri;  
  9. import android.os.Bundle;  
  10. import android.provider.ContactsContract;  
  11. import android.util.Log;  
  12.   
  13. public class ContentProviderUserActivity extends Activity {  
  14.     private static final  String TAG="ContentProviderUserActivity";  
  15. /*    @Override 
  16.  //向数据库插入数据 
  17.     public void onCreate(Bundle savedInstanceState) { 
  18.         super.onCreate(savedInstanceState); 
  19.         setContentView(R.layout.main); 
  20.         ContentResolver contentResolver=this.getContentResolver(); 
  21.         Uri uri=Uri.parse("content://com.jbridge.provider.personprovider/person"); 
  22.         ContentValues values=new ContentValues(); 
  23.         values.put("name", "刘德华"); 
  24.         values.put("age",(short)55); 
  25.         contentResolver.insert(uri, values); 
  26.     }*/  
  27.       
  28.    /* @Override 
  29.      //向数据库修改数据 
  30.     public void onCreate(Bundle savedInstanceState) { 
  31.         super.onCreate(savedInstanceState); 
  32.         setContentView(R.layout.main); 
  33.         ContentResolver contentResolver=this.getContentResolver(); 
  34.         Uri uri=Uri.parse("content://com.jbridge.provider.personprovider/person/4"); 
  35.         ContentValues values=new ContentValues(); 
  36.         values.put("name", "haha"); 
  37.         values.put("age",(short)55); 
  38.         contentResolver.update(uri, values, null, null); 
  39.     }*/  
  40.       
  41.      /*@Override 
  42.        //向数据库删除数据 
  43.         public void onCreate(Bundle savedInstanceState) { 
  44.             super.onCreate(savedInstanceState); 
  45.             setContentView(R.layout.main); 
  46.             ContentResolver contentResolver=this.getContentResolver(); 
  47.             Uri uri=Uri.parse("content://com.jbridge.provider.personprovider/person"); 
  48.             contentResolver.delete(uri, "personid>?",new String[]{String.valueOf(18)} ); 
  49. //          contentResolver.delete(uri,null,null ); 
  50.         }*/  
  51.       
  52.     /*@Override 
  53.      //向数据库查询数据 
  54.     public void onCreate(Bundle savedInstanceState) { 
  55.         super.onCreate(savedInstanceState); 
  56.         setContentView(R.layout.main); 
  57.         ContentResolver contentResolver=this.getContentResolver(); 
  58.         Uri uri=Uri.parse("content://com.jbridge.provider.personprovider/person"); 
  59.      Cursor cursor=contentResolver.query(uri, new String[]{"personid","name","age"}, null, null, "personid desc"); 
  60.     while (cursor.moveToNext()) { 
  61.         Log.i(TAG, "personid  "+cursor.getInt(0)); 
  62.     } 
  63.     cursor.close(); 
  64.     }*/  
  65.       
  66.       
  67.     @Override  
  68.      //向电话本取得数据  
  69.    public void onCreate(Bundle savedInstanceState) {  
  70.        super.onCreate(savedInstanceState);  
  71.        setContentView(R.layout.main);  
  72.        ContentResolver contentResolver=this.getContentResolver();  
  73.         
  74.     Cursor cursor=contentResolver.query(ContactsContract.Contacts.CONTENT_URI,nullnullnullnull);  
  75.    while (cursor.moveToNext()) {  
  76.     int contactID=cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));  
  77.     String name=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));  
  78.     Log.i(TAG, "contactid="+contactID+",name="+name);  
  79.     Cursor phones=contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+contactID,nullnull);  
  80.     StringBuilder sb=new StringBuilder();  
  81.     while (phones.moveToNext()) {  
  82.         String phoneNumber=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));  
  83.         sb.append(phoneNumber).append(",");  
  84.     }  
  85.     sb.deleteCharAt(sb.lastIndexOf(","));  
  86.     phones.close();  
  87.     Log.i(TAG, sb.toString());  
  88.    
  89.      
  90.    Cursor emails = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,    
  91.            null,    
  92.            ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + contactID,    
  93.            nullnull);    
  94.            while (emails.moveToNext()) {    
  95.             // This would allow you get several email addresses    
  96.             String emailAddress = emails.getString(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));  
  97.             Log.i(TAG, "emailAddress="+ emailAddress);  
  98.            }    
  99.            emails.close();    
  100.      
  101.    cursor.close();  
  102.     }  
  103.       
  104.     }  
  105.       
  106. }  
 
在AndroidManifest.xml中添加
Xml代码  收藏代码
  1. <uses-permission android:name="android.permission.READ_CONTACTS"/>  
  2.    <uses-permission android:name="android.permission.READ_PERSON_DB"/>  
 


  • db.rar (71 KB)
  • 下载次数: 193
  • contentProviderUser.rar (40.8 KB)
  • 下载次数: 209
  • 查看图片附件
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 5个月孩子厌奶怎么办 怀孕后特别不爱吃水果怎么办 宝宝吃了无比滴怎么办 婴儿上火怎么办吃什么可以去火 肚子胀怎么办最快的方法 40天婴儿拉水怎么办 8个月宝宝坐不稳怎么办 宝宝段奶不吃奶粉怎么办 3个月宝宝头睡偏了怎么办 2个月婴儿抱着睡怎么办 两个半月的宝宝睡眠少怎么办 七个月宝宝不愿意坐怎么办 一个多月的宝宝老是哭闹怎么办 宝宝头老往后仰怎么办 8个月宝宝不会爬怎么办 孩子个头长得慢怎么办 宝宝个头长得慢怎么办 婴儿个头长得慢怎么办 11个月宝宝认生怎么办 3个月宝宝认人怎么办 3个月的宝宝认生怎么办 两个月的宝宝睡觉一惊一惊怎么办 六个月宝宝不喜欢喝水怎么办 三岁宝宝尿多怎么办 一岁的宝宝尿少怎么办 一岁宝宝尿黄怎么办 三岁宝宝尿黄怎么办 5个月宝宝认生怎么办 3岁宝宝怕生胆小怎么办 2岁宝宝怕生胆小怎么办 1岁半宝宝认生怎么办 宝宝认人一直哭怎么办 七个月宝宝认人怎么办 一个月宝宝认人怎么办 2个多月宝宝认人怎么办 婴儿认人一直哭怎么办 六个月宝宝认人怎么办 十一个月宝宝断奶后辅食怎么办 6个月宝宝不会坐怎么办 7个月宝宝坐不住怎么办 三个月宝宝白天闹觉怎么办