- Uri
举例:content://org.crazyitxxxxx/words
- 协议部分:content:// 这部分是Android的ContentProvider规定默认协议
- authorities部分,org.crazyitxxxxx :ContentProvider的authorities.系统根据这个来操作那个ContentProvider。
- 资源部分:words。这部分是动态改变的。
Uri还支持content://org.crazyitxxxxx/words/2
含义:访问Word数据中ID为2的记录
Uri还支持content://org.crazyitxxxxx/words/2/word
含义:访问Word数据中ID为2的记录的Word字段
- ContentProvider所操作的数据除了来自数据库,也可以来自文件,xml等网络存储。
- ContentUri的withAppendId(uri,id)可以为路径加上id部分
parseId可以解析ID值
- 开发ContentProvider流程
- 创建ContentProvider子类,实现query(),insert(),update(),delete()方法
- 在AndroidManifest.xml文件中注册该ContentProvider,指定authorities属性。子元素<andorid:exported>指定是否能被其他应用调用
- 使用Context的getContentResolver()方法调用query(),insert(),updata(),delete()方法,实际上就是调用对应的Uri的相应方法。
- ContentProvider的保安UriMacher
- 创建
public static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);、
- 注入Uri,以及指定的UriMacher对应的标志code
static {
uriMatcher.addURI(Constants.Authorities, "words", STATUS_WORDS);
uriMatcher.addURI(Constants.Authorities, "word/#", STATUS_WORD);
}
- int match(uri) 根据注册的uri得到code
int status = uriMatcher.match(uri);
switch (status) {
case STATUS_WORDS:
rows = wdb.delete(Constants.DictTable.TABLE, selection, selectionArgs);
System.out.println("删除 完成 rows "+rows);
break;
case STATUS_WORD:
long id = ContentUris.parseId(uri);
String clause = Constants.DictTable.ID+" = "+id;
String conditions = clause +" and "+ selection;
rows = wdb.delete(Constants.DictTable.TABLE,conditions,selectionArgs);
System.out.println("rows :"+rows);
break;
}
- 监听ContentProvider的数据改变之ContentObserver
- getContext().getContextResolver().notifyChange(uri,null);在insert,delete,update中导致数据改变,调用此方法,null,就会通知注册在该Uri上的所用ContentObserver
- 注册监听。getContentResolver().registerContentObserver(uri,boolean,Observer),实现Observer类重写回调方法OnChanged()
代码:
public class MainActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 为content://sms的数据改变注册监听器
getContentResolver().registerContentObserver(
Uri.parse("content://sms"), true,
new SmsObserver(new Handler()));
}
// 提供自定义的ContentObserver监听器类
private final class SmsObserver extends ContentObserver
{
public SmsObserver(Handler handler)
{
super(handler);
}
public void onChange(boolean selfChange)
{
// 查询发送箱中的短信(处于正在发送状态的短信放在发送箱)
Cursor cursor = getContentResolver().query(
Uri.parse("content://sms/")
, null, null, null, null);
// 遍历查询得到的结果集,即可获取用户正在发送的短信
while (cursor.moveToNext())
{
StringBuilder sb = new StringBuilder();
// 获取短信的发送地址
sb.append("address=").append(cursor
.getString(cursor.getColumnIndex("address")));
// 获取短信的标题
sb.append(";subject=").append(cursor
.getString(cursor.getColumnIndex("subject")));
// 获取短信的内容
sb.append(";body=").append(cursor
.getString(cursor.getColumnIndex("body")));
// 获取短信的发送时间
sb.append(";time=").append(cursor
.getLong(cursor.getColumnIndex("date")));
System.out.println("发送短信:" + sb.toString());
}
}
}
- 系统的ContentProvider
- 管理联系人的ContentProvider
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contactList = (ListView) findViewById(R.id.lv_contact);
initData();
}
private void initData() {
Uri consUri = ContactsContract.Contacts.CONTENT_URI;
Uri phoUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
Uri emailUri = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
Uri uri = Uri.parse("content://com.android.contacts");
Uri rawContactUri = uri.withAppendedPath(uri, "raw_contacts");
Uri dataUri = uri.withAppendedPath(uri, "data");
Uri mimeTypeUri = Uri.withAppendedPath(uri, "mimetypes");
Cursor rawContactCousor = getContentResolver().query(rawContactUri, new String[]{"contact_id"}, null, null, null);
while (rawContactCousor.moveToNext()) {
String contactId = rawContactCousor.getString(0);
System.out.println(contactId);
Cursor dataCursor = getContentResolver().query(dataUri, new String[]{"mimetype", "data1"}, "raw_contact_id = ?",new String[]{contactId}, null);
String mimeType = null;
while (dataCursor.moveToNext()) {
mimeType = dataCursor.getString(0);
// Cursor mimeTypeCursor = getContentResolver().query(mimeTypeUri, new String[]{"mimetype"}, "raw_contact_id = ?", new String[]{StringId}, null);
/* while (mimeTypeCursor.moveToNext()) {
mimeType = mimeTypeCursor.getString(0);
System.out.println("mimeType: " + mimeType);
}
mimeTypeCursor.close();*/
String type = null;
if ("vnd.android.cursor.item/email_v2".equals(mimeType)) {
type = "email";
} else if ("vnd.android.cursor.item/phone_v2".equals(mimeType)) {
type = "phomeNumber";
} else if ("vnd.android.cursor.item/name".equals(mimeType)) {
type = "name";
}
String data = dataCursor.getString(1);
System.out.println("name: "+type+" data: "+data);
}
dataCursor.close();
}
rawContactCousor.close();
}
2.获取短信数据:(区别于用Broadcast获取短信数据)
public class MainActivity extends AppCompatActivity {
private Uri smsUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
smsUri = Uri.parse("content://sms");
initData();
}
private void initData() {
Cursor smsCursor = getContentResolver().query(smsUri, null, null, null, null);
while(smsCursor.moveToNext()){
String address = smsCursor.getString(smsCursor.getColumnIndex("address"));
String body = smsCursor.getString(smsCursor.getColumnIndex("body"));
System.out.println("address: "+address+" body: "+body);
}
}
}