上面两篇我们讲了ContentProvider如何使用
Android进阶:步骤2:ContentProvider初体验
https://blog.csdn.net/qq_17846019/article/details/83313922
Content Provider 解析URI的方法 UriMatcher的用法和自带的解析方法
https://blog.csdn.net/qq_17846019/article/details/83338284
系统短信箱的Uri分成以下几个部分
可以跟你你想要拿的信箱加以区分
读取信箱分成以下三个步骤:
在内容处理者(ContentResolver)中处理
1.配置文件中添加读写信箱的权限,和android6.0后动态申请权限
2.获取内容处理者对象
3.查询方法返回Cursor对象
4.解析Cursor
AndroidManifest.xml中添加读信息的权限
android6.0后要动态申请权限
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ContentResolver contentResolver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.申请权限 在配置文件中写还有动态申请
checkPermission(this);
//2拿的内容处理者对象
contentResolver = getContentResolver();
findViewById(R.id.sms_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//拿的发信箱的uri
Uri uri = Uri.parse("content://sms/sent");
//参数1:uri
//参数2:查询指定列范围,null为查询所有
//参数3:查询条件,不指定
//参数4:查询条件数组,和参数2搭配使用,不指定
//参数5:排序
Cursor c = contentResolver.query(uri, null, null, null, null);
//3.解析Uri
//遍历Cursor
while (c.moveToNext()) {
String msg = "";
// //显示每条发信箱的内容
// //遍历该行的列
// for(int i=0;i
Log打印结果:
这是我发信箱的短信
拿到的短信:
E/TAG: msg=95559 66666
msg=10086 ???
读取联系人和读取短信的类似
但稍微有点复杂,因为联系人的姓名和电话号码是放在不同的两个表的,需要进行两次查询
联系人姓名是主表,id是主键,电话号码所在的表是从表,可以通过主表的id主键来查到对应从表的电话号码
步骤:
1.添加权限
2.查询操作,返回Cursor
3.解析Cursor
代码:
1.添加权限
6.0后动态申请权限写在一起了后面就不写了
//android6.0之后要动态获取权限
private void checkPermission(Activity activity) {
// Storage Permissions
final int REQUEST_EXTERNAL_STORAGE = 1;
String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_SMS,
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS
};
try {
//检测是否有读短信箱的权限
int permission = ActivityCompat.checkSelfPermission(MainActivity.this,
"android.permission.READ_SMS");
//检查是否有读联系人的权限
int permission2 = ActivityCompat.checkSelfPermission(MainActivity.this,
"android.permission.READ_CONTACTS");
//检查是否有写联系人的权限
int permission3 = ActivityCompat.checkSelfPermission(MainActivity.this,
"android.permission.WRITE_CONTACTS");
if (permission != PackageManager.PERMISSION_GRANTED ||
permission2!= PackageManager.PERMISSION_GRANTED ||
permission3 != PackageManager.PERMISSION_GRANTED) {
// 没有某一个权限,去申请相应权限,会弹出对话框
ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
findViewById(R.id.read_contact_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//对应联系人而言,他们的存储方式是将姓名和其他内容(电话号码)由不同的ContentProvider操作的
//首先想象联系人和其他内容属于不同的表
//而姓名所在的表示主表,其他内容位于从表
//而主表的主键id在从表中作为外键使用
//1.查姓名的uri
Uri uri1 = ContactsContract.Contacts.CONTENT_URI;
Cursor c1 = contentResolver.query(uri1, null, null, null, null);
while (c1.moveToNext()) {
//姓名的列
// ContactsContract.Contacts.DISPLAY_NAME;
// //主键id的列
// ContactsContract.Contacts._ID;
//同样可以遍历所有列,但这里只要看姓名和电话
String name = c1.getString(c1.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String id = c1.getString(c1.getColumnIndex(ContactsContract.Contacts._ID));
//继续访问下一个Uri拿到对应从表的电话号码
//2.查找电话的Uri
Uri uri2 = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
//在从表外键id的查询条件
String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?";
//通过这个外键找到相应的电话号码
Cursor c2 = contentResolver.query(uri2,
null,
selection,//查询条件
new String[]{id},//查询条件的值
null);
//每一id(一个人)都可以有多个电话号码
//还有要将每个电话号码拿出来
while (c2.moveToNext()) {
//取出电话号码的列
String number = c2.getString(c2.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
name += " 电话:" + number;
}
Log.e("TAG", "姓名是:" + name + " id是:" + id);
}
}
});
输出结果:
E/TAG: 姓名是:Cmcc 电话:1 387-891-2345 id是:1
E/TAG: 姓名是:Love 电话:1 827-891-2345 电话:1 527-891-2345 id是:2
更改一个查询的语句,添加上查询条件
Cursor c1 = contentResolver.query(
uri1,
null,
ContactsContract.Contacts.DISPLAY_NAME+"=?",//查询条件
new String[]{"Love"},//查询条件值数组
null);
就会只显示Love的电话
E/TAG: 姓名是:Love 电话:1 827-891-2345 电话:1 527-891-2345 id是:2
上面权限的就不写了,在上一个获取联系人
findViewById(R.id.add_contact_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//1.往一个ContentProvider中插入一条空数据,获取新的id
//2.利用刚刚生成的id分别组合姓名和电话号码往另一个ContentProvider插入数据
ContentValues values=new ContentValues();
//拿到插入空数据的uri
Uri uri=ContactsContract.RawContacts.CONTENT_URI;
//返回的uri后面追加有id
Uri returnUri=contentResolver.insert(uri,values);
//获取这个id
long id= ContentUris.parseId(returnUri);
//插入姓名
//获取插入姓名的Uri
Uri nameUri=ContactsContract.Data.CONTENT_URI;
//放姓名的列名
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,"新联系人");
//放id的列名
values.put(ContactsContract.Data.RAW_CONTACT_ID,id);
//指定添加的添加的数据类型(在ContentProvider 有一个获取类型的方法)
values.put(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
contentResolver.insert(nameUri,values);
//插入电话号码
//先清空之前的数据
values.clear();
//插电话号码
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER,"13878999999");
//放id的列名
values.put(ContactsContract.Data.RAW_CONTACT_ID,id);
//指定数据类型
values.put(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
//对于电话号码,可能是手机号或者是座机号码
//所以要指定电话号码的类型是移动电话
values.put(ContactsContract.CommonDataKinds.Phone.TYPE,ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
contentResolver.insert(ContactsContract.Data.CONTENT_URI,values);
}
});
效果演示