ContentProvider 数据供应器_读取联系人信息
Android 系统将所有数据都规定为对外私有,也就是无法直接访问应用程序之外的数据。如果需要访问其他应用程序的数据或向其他应用程序提供数据,就需要使用 ContentProvider(数据供应器)。该类位于 android.content 包中,为存储和获取数据提供了统一的接口。
Android 为常见的一些数据提供了默认的 ContentProvider,包括音频、视频、图片和通信录等,使用时需要得到相应访问的权限。 ContentProvider 常用方法说明:
1、Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder); 查询操作,通过 uri 查询数据,返回 Cursor (这个查询语法类似于 Hibernate)
2、Uri insert(Uri uri, ContentValues values); 插入操作,将数据插入到 uri 指定内容,数据需要封装到 ContentValues 对象中。
3、int update(Uri uri, ContentValues values, String selection, String[] selectionArgs); 更新操作。
4、int delete(Uri uri, String selection, String[] selectionArgs); 删除操作。
外界程序在访问 ContentProvider 中的数据时,并不是进行直接操作,而是借助 ContentResolver 类,该类也位于 android.content 包中,多数方法都是由 Static 或 final 修饰,它是作为一个工具类来使用的。
ContentResolver 对象可以通过 getContentResolver() 方法(Content 类的方法)得到,其中提供的方法与 ContentProvider 类中的方法对应。使用 ContentProvider 对象读取数据设计的类有 Uri(数据统一标志)、ContentResolver(读取数据的功能)、Cursor(包含结果数据的游标)。
1 ContentResolver cr = getContentResolver(); 2 Cursor cursor = cr.query(ContactsContract.Data.CONTENT_URI, data, null, null, null);
ContentResolver 类的 query 方法和 managedQuery 方法具有相同的参数要求,查询方法参数明显如下:
1、Uri uri:待查询参数(Content Provider)的 Uri
2、String[] projection:需要查询的字段,相当于 Select 语句后面的字段信息
3、String selection:查询的条件,相当于 WHERE 子句后面的条件
4、String[] selectionArgs:查询条件的值,给 WHERE 子句中的占位参数传值
5、String sortOrder:排序条件,相当于 Order by 子句。
ContactsContract.Data.CONTENT_URI 是联系人数据的 Uri,是系统级 Uri。data 数组保存需要查询的字段值,都引用了 ContactsContract.Data 类的属性。ContactsContract.Data.MIMETYPE 属性是标明该数据是何种类型的信息。Phone.CONTENT_ITEM_TYPE 即为电话号码。查询的结果会返回 Cursor 对象,即游标,可以移动,具有生命周期。
总之,使用 ContentProvider 查询其他程序中暴露的数据比较简单:
1、确定需要查询数据的 Uri(Adndroid 系统中有很多原生态的 Uri);
2、使用 ContentResolver 类中的 query 方法查询;
3、检索 Cursor,处理相应数据。
Uri 类位于 android.net 包中,代表了要操作的数据,主要包含两部分的信息:需要操作的 ContentProvider 与 ContentProvider 中的具体数据。一个 Uri 由以下几个部分构成:如
content://com.example.transportationprovider/trains/122
A:前缀标志,任何 Uri 都有一个固定的前缀,Content:// 标明这是 ContentProvider 中使用的 Uri。
B: 数据的权限标志,com.example.transportationprovider,要求唯一。
C: 路径标志,trains,代表 Uri 所要访问的具体数据表。
D: ID 信息,122,C 中数据表的某一个 ID 值。
联系人数据表的 Uri 是 ContactsContract.Data.CONTENT_URI 常量,对应的具体的 Uri 字符串是:content://com.android.contacts/data。说明要访问 data 表中的全部数据。如果改为:content://com.android.contacts/data/2,则表明访问 data 表中 ID 为 2 的那条记录。可以通过 Uri.parse(content://com.android.contacts/data) 来获得 ContactsContract.Data.CONTENT_URI 对象。
UriMatcher 类用于匹配 Uri 的检验,主要涉及方法 addURI(String authority, String path, int code) 和 match(Uri uri)。
1 // 匹配检验 2 UriMatcher uMatcher = new UriMatcher(UriMatcher.NO_MATCH); 3 uMatcher.addURI("com.android.contacts", "data", 1); 4 int r = uMatcher.match(ContactsContract.Data.CONTENT_URI);
创建 UriMatcher 对象,传入常量 NO_MATCH,当匹配不成功时会返回该常量的值。使用 addURI 方法添加匹配样式,相当于模板,供待检验的 Uri 与此对比,可以多次调用此方法,添加多个模板。该方法有三个参数:
1、Uri 的数据权限;
2、路径标识,可以使用通配符(*用于通配文本,#用于通配数字);
3、匹配成功时的返回值,通过与此值对比,可以判定是否匹配成功。
match 方法用于匹配 Uri,若匹配成功,返回 addURI 方法中的第三个参数,若不成功,返回构造 UriMatch 时传入的参数。
ContentUris 类用于操作 Uri 路径后面的 ID 部分,它有如下两个比较实用的方法。
1、static Uri withAppendedId(Uri contentUri, long id),向 Uri 路径后面追加 id;
2、static long parseId(Uri contentUri),获取 Uri 中的 id 值。
开启权限
<uses-permission android:name="android.permission.READ_CONTACTS"/>
1 public class MainActivity extends Activity { 2 Button bt; 3 TextView tv; 4 5 @Override 6 public void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 9 setContentView(R.layout.main); 10 bt = (Button) findViewById(R.id.bt); 11 tv = (TextView) findViewById(R.id.tv); 12 bt.setOnClickListener(new OnClickListener(){ 13 14 @Override 15 public void onClick(View v) { 16 //显示所有联系人 17 showAllContacts(); 18 } 19 }); 20 } 21 22 // 查询所有联系人信息 23 public void showAllContacts(){ 24 25 // 构造需要查询信息的字段 26 String data[] = {ContactsContract.Data._ID, // 联系人 ID 唯一、必须 27 ContactsContract.Data.DISPLAY_NAME, // 联系人名 28 ContactsContract.Data.MIMETYPE, 29 ContactsContract.Data.DATA1}; //电话 30 31 // 查询指定资源的数据 32 //Cursor cursor = managedQuery(ContactsContract.Data.CONTENT_URI, data, null, null, null); 33 ContentResolver cr = getContentResolver(); 34 Cursor cursor = cr.query(ContactsContract.Data.CONTENT_URI, data, null, null, null); 35 Log.i("Tag", ContactsContract.Data.CONTENT_URI.toString()); 36 37 // 匹配检验 38 UriMatcher uMatcher = new UriMatcher(UriMatcher.NO_MATCH); 39 uMatcher.addURI("com.android.contacts", "data", 1); 40 int r = uMatcher.match(ContactsContract.Data.CONTENT_URI); 41 Log.i("Tag", "匹配结果:" + r); 42 43 cursor.moveToFirst(); 44 StringBuffer txt = new StringBuffer(); 45 while(!cursor.isAfterLast()){ 46 Log.i("Tag", cursor.getString(2)); 47 // 只显示有电话号码的联系人 48 if(cursor.getString(2).equalsIgnoreCase(Phone.CONTENT_ITEM_TYPE)){ 49 txt.append("ID: "+cursor.getString(0)+"\t"); 50 txt.append("Name: "+cursor.getString(1)+"\t"); 51 txt.append("Phone: "+cursor.getString(3)); 52 txt.append('\n'); 53 } 54 cursor.moveToNext(); 55 } 56 tv.setText(txt); 57 } 58 }
 
                    
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号