ContentProvider是一个不同应用间进行数据共享的标准API,我们通过ContentResolver来操作ContentProvider提供的数据。它们之间通过被ContentProvider绑定的uri来间接进行操作数据。
而uri的格式是content://host:port/path,其中对于ContentProvider来说,content://是固定的,不能更改,就像如果我们要上网,就会输入http://一样,但如果不是用ContentProvider,就可以是别的格式,列如访问手机中的某一首歌曲,则Uri格式是file:///storage/sdcard0/平凡之路.mp3,通常我们都会用uri.parse()将普通字符串转换为uri的标准格式。
这里附上一段代码,是照着书上敲的关于调用系统联系人相关信息的,通过这个列子可以对其中一些知识更好理解。
public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case (PICK_CONTACT): if (resultCode == Activity.RESULT_OK) { Uri contactData = data.getData();//其实就是获得标识ContentProvider的Uri,即获得我们要操纵数据的Uri CursorLoader cursorLoader = new CursorLoader(this, contactData, null, null, null, null);//创建一个CursorLoader Cursor cursor = cursorLoader.loadInBackground();//获得符合条件的查询结果 if (cursor.moveToFirst()) { String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); String phoneNumber = "暂时未输入号码"; Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, contactId,null,null); // ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);这里是通过生成一个contentprovider,调用它的查询方法来获得数据 if (phones.moveToFirst()) { phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); } phones.close(); EditText show = (EditText) findViewById(R.id.show); show.setText(name); EditText phone = (EditText) findViewById(R.id.phone); phone.setText(phoneNumber); } cursor.close(); } break; } }
我们在oncreate()方法中通过intent.setAction(Intent.ACTION_GET_CONTENT); intent.setType("vnd.android.cursor.item/phone");startActivityForResult(intent, PICK_CONTACT)可以找到intent对应的系统组件,通过上面的OnActivityResult()得到返回的联系人信息。关于这两个函数以及其中的RequestCode及ResultCode,这里推荐一篇博文,写的很清楚,http://www.cnblogs.com/linjiqin/archive/2011/06/03/2071956.html。
上面代码中提到了CursorLoader,首先要明白这里的cusor与数据库中的cursor不同,数据库中的是代表游标,我感觉有点像指针,可以移动来指向不同的数据,而这里的则相当于一个Result,即结果集。我觉得可以把cursorloader看做是一个查询工具,我们通过这个查询工具来从提供的Uri中获得数据。cursorloader继承自AsynctaskLoader,而AsyntaskLoader是一个异步查询机制,Asyntaskloader继承自loader。
这里提到一个概念,异步查询,看到过一个很形象的描绘,好比你在打游戏,当你点击后,画面上什么都没有,过了一会,图片动画人物都同时加载出来了,这就是同步。但如果你先看到一个人物,当人物运行一会后,图片也慢慢出来了,这时就是异步。
在cursor中有movetoXXX()方法,要注意这些方法中,数据都是先指向第一个数据之前,这样我们才可以通过move类型的方法去移动。关于cursor,这里也推荐一篇文章,不过自己还没看太懂,就不做赘述了http://www.sxrczx.com/pages/kohoh1992.github.io/cursor-auto-sync/index_1431878338570.html。
ps:关于这一节还有很多知识,现在还没理解的很清楚,只能后续补充了。。。
上面提到的第一段代码,现在也还有问题,每次选择联系人时,都会显示同一个号码