现在的位置: 首页 > 移动开发 > 正文

Android入门进阶教程(20)-ContentProvider 数据共享

2019年09月08日 移动开发 ⁄ 共 12876字 ⁄ 字号 评论关闭

1、使用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); 
-该方法用于外部应用更新ContenProvider数据; 
* public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder); 
-该方法用于外部应用从ContentProvider获取数据; 
* public String getType(Uri uri); 
-该方法用于返回当前Url 所代表数据的MIME类型, 

1.2 public String getType(Uri uri);该方法的使用介绍: 
该方法用于返回当前Url所代表数据的MIME类型。如果操作的数据属于集合类型,那么MIME类型字符串 
应该以vnd.android.cursor.dir/开头; 
例如:要得到所有person记录的 Uri为content://cn.itcast.provider.personprovider/person,那 
么返回的MIME类型字符串应该为:vnd.android.cursor.dir/person。 
如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头; 
例如:得到id为10的person的记录,Uri为:content://cn.itcast.provider.personprovider/person/10, 
那么返回的MIME类型字符串应该为:vnd.android.cursor.item/person; 

2、使用ContentResolver操作ContentProvider中的数据: 
* 工具类:ContentResolver 
当外部的应用需要对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[] projectionm,String selection ,String[] selectionArgs,String sortOrder); 
-该方法用于从Content中获取数据; 

【注:以上所有方法的第一个参数Uri,代表要操作的ContentProvider和对其中的什么数据进行操作;】 
例如:Uri.parse("content://cn.itcast.providers.personprovider/person/10"); 
表示:对主机名为:cn.itcast.providers.personprovider的ContentProvider进行操作,操作数据表person中id为 
10的记录; 

案例:模拟通讯录的操作:添加数据,删除,修改,查看; 
使用小贴士: 

首先:加入读写联系人信息的权限: 
<uses-permission android:name="android.permission.READ_CONTACTS"/> 
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/> 
    
    需要使用到的Uri: 
    content://com.android.contacts/contacts 操作的数据是联系人的Uri; 
    content://com.android.contacts/data/phone 联系人电话Uri; 
    content://com.android.contacts/data/emails 联系人Email Uri; 
    
    注:表中不同的MIME,对应的Uri是不同的,如需获取对应类型的信息,那么Uri必须相对应; 
    
    具体实现代码: 

Java代码  收藏代码
  1. package com.svse.contentprovider;  
  2.   
  3. import android.net.Uri;  
  4. import android.os.Bundle;  
  5. import android.provider.ContactsContract;  
  6. import android.provider.ContactsContract.CommonDataKinds.Email;  
  7. import android.provider.ContactsContract.CommonDataKinds.Phone;  
  8. import android.provider.ContactsContract.CommonDataKinds.StructuredName;  
  9. import android.provider.ContactsContract.Data;  
  10. import android.provider.ContactsContract.RawContacts;  
  11. import android.app.Activity;  
  12. import android.content.ContentResolver;  
  13. import android.content.ContentUris;  
  14. import android.content.ContentValues;  
  15. import android.content.UriMatcher;  
  16. import android.database.Cursor;  
  17. import android.view.Menu;  
  18. import android.view.View;  
  19. import android.view.View.OnClickListener;  
  20. import android.widget.Button;  
  21. import android.widget.Toast;  
  22.   
  23. public class MainActivity extends Activity {  
  24.   
  25.     private Button insert ,delete,update,read;  
  26.     protected void init(){  
  27.         insert = (Button) findViewById(R.id.insertContact);  
  28.         delete = (Button) findViewById(R.id.deleteContacts);  
  29.         update = (Button) findViewById(R.id.updateContacts);  
  30.         read = (Button) findViewById(R.id.readContact);  
  31.     }  
  32.     protected void onCreate(Bundle savedInstanceState) {  
  33.         super.onCreate(savedInstanceState);  
  34.         setContentView(R.layout.main);  
  35.         /* 初始化组件对象 */  
  36.         init();  
  37.   
  38.         /* 为read设置按钮点击事件监听器 */  
  39.         read.setOnClickListener(new OnClickListener() {  
  40.   
  41.             public void onClick(View v) {  
  42.                 readContacts();       
  43.             }  
  44.         });  
  45.           
  46.         insert.setOnClickListener(new OnClickListener() {  
  47.               
  48.             @Override  
  49.             public void onClick(View v) {  
  50.                 // TODO Auto-generated method stub  
  51.                 insertContacts();  
  52.             }  
  53.         });  
  54.   
  55.         delete.setOnClickListener(new OnClickListener() {  
  56.               
  57.             @Override  
  58.             public void onClick(View v) {  
  59.                 // TODO Auto-generated method stub  
  60.                 deleteContacts();  
  61.             }  
  62.         });  
  63.           
  64.         update.setOnClickListener(new OnClickListener() {  
  65.               
  66.             @Override  
  67.             public void onClick(View v) {  
  68.                 // TODO Auto-generated method stub  
  69.                 //updateContacts();  
  70.             }  
  71.         });  
  72.     }  
  73.   
  74.     /* 读取联系人信息 */  
  75.     public void readContacts(){  
  76.         /* 获取ContentResolver对象,使用getContentResolver()方法 */  
  77.         ContentResolver cr = this.getContentResolver();  
  78.   
  79.         /**************************************联系人信息**********************************************/  
  80.         /* 执行查询操作,使用query();方法 */  
  81.         /* 参数说明: 
  82.          * @ uri : 操作ContentProvider的Uri; 
  83.          * @ projection :查询的列; 
  84.          * @ selecion   :查询条件; 
  85.          * @ selectionArgs  :条件对应参数; 
  86.          * @ sortOrder      :排序方式; 
  87.          */  
  88.         /* 获取联系人信息: Uri:ContactsContract.Contacts.CONTENT_URI*/  
  89.         Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, nullnullnullnull);          
  90.   
  91.         /* 操作游标,获取数据 */  
  92.         for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()){  
  93.   
  94.             /* 保存当前联系人的所有信息 */  
  95.             StringBuffer sb = new StringBuffer();  
  96.   
  97.             /* 获取联系人ID */  
  98.             String contactID = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));  
  99.             sb.append("ID:"+contactID+"\n");  
  100.             /* 获取联系人姓名 */  
  101.             String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));  
  102.             sb.append("姓名:"+name+"\n");  
  103.             /**********************************************************************************************/  
  104.             /* 通讯录 表 的特点:保存数据是按行保存,即:每个数据信息占一行,每行中该种属性能有多个值: 
  105.              * 例如 : 一个人的电话号码能有多个;即:一个contactID下有多个phone; */  
  106.             /**********************************************************************************************/  
  107.   
  108.             /****************************获取电话号码*********************************************/  
  109.             //ContactsContract.CommonDataKinds.Phone.CONTENT_URI    获取Phone对应MIME类型的Uri;  
  110.             //ContactsContract.CommonDataKinds.Phone.CONTACT_ID     获取表中的联系人ID;  
  111.             Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"=?"new String[]{contactID}, null);  
  112.             while(phone.moveToNext()){  
  113.                 String phoneNumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));  
  114.                 sb.append("phone:"+phoneNumber+"\n");  
  115.                 //Toast.makeText(MainActivity.this, "_ID="+contactID+" name="+name+" phone:"+phoneNumber, 1000).show();  
  116.             }  
  117.             /* 游标使用后要关闭 */  
  118.             phone.close();  
  119.             /**********************************************************************************************/  
  120.   
  121.             /************************************获取Email*************************************************/  
  122.             Cursor email = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID+"=?"new String[]{contactID},null);  
  123.             while(email.moveToNext()){  
  124.                 String emailAddress = email.getString(email.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));  
  125.                 sb.append("emailAddress:"+emailAddress+"\n");  
  126.                 //Toast.makeText(MainActivity.this, "_ID="+contactID+" name="+name+" Email:"+emailAddress, 1000).show();  
  127.             }  
  128.             email.close();  
  129.             /**********************************************************************************************/  
  130.   
  131.   
  132.             Toast.makeText(MainActivity.this, sb.toString(), 1000).show();  
  133.         }  
  134.         cursor.close();  
  135.   
  136.   
  137.     }  
  138.   
  139.     /* 添加联系人 */  
  140.     public void insertContacts(){  
  141.           
  142.         /*************************************方式一*******************************************************/  
  143.         /* 首先:需要向RawContacts.CONTENT_URI 执行一个空值的插入,目的是获取系统返回的rawConatactId , 
  144.          * 这是后面插入data表的依据,只有执行空值的插入,才能使插入的联系人在通讯录里可见*/  
  145.         ContentValues values = new ContentValues();  
  146.   
  147.         /* 向 RawContacts.CONTENT_URI执行一个空值的插入,返回rawContactId */  
  148.         Uri rawContactUri = this.getContentResolver().insert(RawContacts.CONTENT_URI, values);  
  149.   
  150.         /* 从Uri路径中获取  ID 的部分 */  
  151.         long rawContactId = ContentUris.parseId(rawContactUri);  
  152.         values.clear();  
  153.           
  154.         /* data表中的数据结构特点:每个数据信息以行进行保存,所以每次添加一行数据 */  
  155.           
  156.         /* 向data表中插入姓名 */  
  157.         values.put(Data.RAW_CONTACT_ID, rawContactId);  //ID  
  158.         values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);    //内容的类型  
  159.         values.put(StructuredName.GIVEN_NAME, "张三峰");  
  160.         this.getContentResolver().insert(android.provider.ContactsContract.Data.CONTENT_URI, values);  
  161.         values.clear();  
  162.           
  163.         /* 向data表中插入移动电话 */  
  164.         values.put(Data.RAW_CONTACT_ID, rawContactId);  
  165.         values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);  
  166.         values.put(Phone.NUMBER, "15337178625");  
  167.         values.put(Phone.TYPE, Phone.TYPE_MOBILE);  //电话的类型:工作电话  移动电话 家庭电话  
  168.         this.getContentResolver().insert(android.provider.ContactsContract.Data.CONTENT_URI, values);  
  169.         values.clear();  
  170.           
  171.         /* 向data表中插入工作电话 */  
  172.         values.put(Data.RAW_CONTACT_ID, rawContactId);  
  173.         values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);  
  174.         values.put(Phone.NUMBER, "02787878989");  
  175.         values.put(Phone.TYPE, Phone.TYPE_WORK);    //电话的类型:工作电话  移动电话 家庭电话  
  176.         this.getContentResolver().insert(android.provider.ContactsContract.Data.CONTENT_URI, values);  
  177.         values.clear();  
  178.           
  179.         /* 向data表中添加Email */  
  180.         values.put(Data.RAW_CONTACT_ID, rawContactId);  
  181.         values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);  
  182.         values.put(Email.DATA, "15337178625@qq.com");  
  183.         values.put(Email.TYPE, Email.TYPE_WORK);    //电话的类型:工作电话  移动电话 家庭电话  
  184.         this.getContentResolver().insert(android.provider.ContactsContract.Data.CONTENT_URI, values);  
  185.         values.clear();  
  186.         Toast.makeText(MainActivity.this"数据添加成功!"1000).show();  
  187.         /********************************************************************************************************/  
  188.           
  189.         /*********************************方式二:批量添加,处于同一个事务**************************************/     
  190.     }     
  191.       
  192.     /* 删除 */  
  193.     public void deleteContacts(){  
  194.         /* 首先获取CotentResolver对象,用于操作ContentProvider */  
  195.         ContentResolver cr = this.getContentResolver();  
  196.           
  197.         /* 思路:删除一个联系人的所有,则根据RAW_CONTACT_ID进行删除 */  
  198.         cr.delete(RawContacts.CONTENT_URI, RawContacts.CONTACT_ID+"=?"new String[]{"1"});  
  199.         Toast.makeText(MainActivity.this"数据删除成功"1000).show();  
  200.     }  
  201. //  
  202. //  /* 修改 */  
  203. //  public void updateContacts(){  
  204. //      ContentResolver cr = this.getContentResolver();  
  205. //        
  206. //      /* 获取ID,需要修改的联系人ID,然后确定修改信息 */  
  207. //      ContentValues values = new ContentValues();  
  208. //      values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);//值的类型  
  209. //      values.put(StructuredName.GIVEN_NAME, "张无忌");  
  210. //      cr.update(ContactsContract.Contacts.CONTENT_URI, values, ContactsContract.Data.DISPLAY_NAME+"=?", new String[]{"张三峰"});  
  211. //      Toast.makeText(MainActivity.this, "修改成功", 1000).show();  
  212. //      readContacts();  
  213. //  }  
  214. //    
  215.       
  216.   
  217.     /*  UriMathcer 类的用法  */  
  218.     public void uriMatcher(){  
  219.         /* 常量UriMatche.NO_MATCH 标示部匹配任何路径的返回码 */  
  220.         UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);  
  221.   
  222.         /* 如果match()方法匹配content://cn.itcast.provider.personprovider/person 路径, 
  223.          * 返回匹配码为 1 
  224.          */  
  225.         /* 添加需要匹配的URL ,如果匹配就会返回匹配码  */  
  226.         sMatcher.addURI("cn.itcast.provider.personprovider""person"1);  
  227.   
  228.         /* # 为通配符 *//* match():方法匹配:content://cn.itcast.provider.personprovider/person/230  
  229.          * 路径, 返回匹配码2 
  230.          *  */  
  231.         sMatcher.addURI("cn.itcast.provider.personprovider""person/#"2);  
  232.   
  233.         /* 按上述添加的规则进行匹配,不同的路径匹配返回不同的匹配码 */  
  234.         int code = sMatcher.match(Uri.parse("content://cn.itcast.provider.personprovider/person/10"));  
  235.   
  236.         /**********************************************************************/  
  237.         //ContentUris 的介绍  
  238.         /* 将字符串转换成Uri */  
  239.         Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person");  
  240.   
  241.         /* 为路径添加ID部分 */  
  242.         Uri resultUri = ContentUris.withAppendedId(uri, 10);  
  243.   
  244.     }  
  245.   
  246. }  


抱歉!评论已关闭.