五ContentProvider权限动态申请 通讯录增删改查
Posted 学习中的owl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五ContentProvider权限动态申请 通讯录增删改查相关的知识,希望对你有一定的参考价值。
五、ContentProvider相关
ContentProvider内容提供者: 负责数据存取,常用于APP进数据共享,跨进程数据存取等…比如读取相册,读取联系人,都是ContentProvider来实现的
- **1.**我们想在自己的应用中访问别的应用,或者说一些ContentProvider暴露给我们的一些数据, 比如手机联系人,短信、相册等!我们想对这些数据进行读取或者修改,这就需要用到ContentProvider了!
- **2.**我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用到ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!
1.权限申请
从android6.0开始,凡是涉及用户隐私的权限(读写短信,读写联系人,拍摄,录音等等),都需要运行时申请,弹窗提醒用户是否授权。用户不授权则无法继续操作
首先在AndroidManifest.xml中声明读取通信录的权限
<uses-permission android:name="android.permission.READ_CONTACTS"/>
运行时动态申请权限,请求用户授权
class TestContentProviderActivity : AppCompatActivity()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
//判断读取通讯录的允许
if(ActivityCompat.checkSelfPermission(this , android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED)
//如果未授权
ActivityCompat.requestPermissions(
this ,
arrayOf(android.Manifest.permission.READ_CONTACTS) ,
100)
else
getContacts() //读取联系人
//读取联系人
private fun getContacts()
Toast.makeText(this, "getContacts", Toast.LENGTH_SHORT).show()
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
)
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode==100 && permissions[0]==android.Manifest.permission.READ_CONTACTS)
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) //表示授予权限
getContacts()
else
Toast.makeText(this,"读取通讯录的权限被拒绝,程序将无法继续工作",Toast.LENGTH_LONG).show()
2.读取通讯录联系人
表名 | 说明 |
---|---|
content://com.android.contacts/data/phones | 读取联系人的表的名字 |
字段 | 说明 |
---|---|
display_name | 用户名 |
Data1 | 手机号 |
//读取联系人
@SuppressLint("Range")
private fun getContacts()
//查询对象
val resolver = contentResolver
//格式化一个uri
val uri = Uri.parse("content://com.android.contacts/data/phones")
//得到一个游标
val cursor = resolver.query(uri, null, null, null, null)?:return
while (cursor.moveToNext())
//获取联系人名字和号码
val displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
val phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
Log.e("ContentProvider", "姓名:$displayName")
Log.e("ContentProvider", "号码:$phoneNumber")
Log.e("ContentProvider", "======================")
cursor.close() //游标关闭!!
3.通信录插入联系人
表名 | 说明 |
---|---|
content://com.android.contacts/data/data | 插入联系人的表的名字 |
content://com.android.contacts/data/raw_contacts | 插入联系人的原始表的名字 |
//插入联系人
private fun insertContact()
/*
* 首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获得系统返回的rawContactId
* 这时后面插入data表的数据,才能使插入的联系人在通讯录里面可见
*/
val resolver = contentResolver
val values = ContentValues()
val rawContactUri = contentResolver!!.insert(ContactsContract.RawContacts.CONTENT_URI, values)!!
val rawContactId = ContentUris.parseId(rawContactUri)
//往data表里写入姓名数据
values.clear() //先把可能存在的数据清空
values.put(ContactsContract.Data.RAW_CONTACT_ID , rawContactId)
values.put(ContactsContract.Data.MIMETYPE , CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) //内容类型
values.put(CommonDataKinds.StructuredName.GIVEN_NAME , "some_name")
resolver.insert(ContactsContract.Data.CONTENT_URI , values)
//往data表里写入电话数据
values.clear() //先把可能存在的数据清空
values.put(ContactsContract.Data.RAW_CONTACT_ID , rawContactId)
values.put(ContactsContract.Data.MIMETYPE , CommonDataKinds.Phone.CONTENT_ITEM_TYPE) //内容类型
values.put(CommonDataKinds.Phone.NUMBER , "1231231234")
values.put(CommonDataKinds.Phone.TYPE , CommonDataKinds.Phone.TYPE_MOBILE) //手机号
resolver.insert(ContactsContract.Data.CONTENT_URI , values)
//往data表里写入Email的数据
values.clear() //先把可能存在的数据清空
values.put(ContactsContract.Data.RAW_CONTACT_ID , rawContactId)
values.put(ContactsContract.Data.MIMETYPE , CommonDataKinds.Email.CONTENT_ITEM_TYPE) //内容类型
values.put(CommonDataKinds.Email.DATA , "some_name@xx.com")
values.put(CommonDataKinds.Email.TYPE , CommonDataKinds.Email.TYPE_HOME) //家庭邮箱
resolver.insert(ContactsContract.Data.CONTENT_URI , values)
4.更新联系人信息
- 根据手机号获取联系人在通讯录的contact_id
@SuppressLint("Range")
fun getContactIdByPhone(phone : Long) : String?
val uri = Uri.parse("content://com.android.contacts/data/phones/filter/$phone")
val resolver = contentResolver
val cursor = resolver.query(uri, arrayOf(ContactsContract.Data.CONTACT_ID), null, null, null)?:return null
if (cursor.moveToNext())
val contractId = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID))
return contractId
return null
- 更新联系人的姓名
//更新联系人
private fun updateContact()
val contractId = getContactIdByPhone(234524)
if(contractId == null)
Toast.makeText(this , "联系人不存在,无法更新" , Toast.LENGTH_LONG).show()
return
val values = ContentValues()
values.put(ContactsContract.Data.MIMETYPE , CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
values.put(CommonDataKinds.StructuredName.GIVEN_NAME, "new_name")
contentResolver.update(
ContactsContract.Data.CONTENT_URI,
values,
"$ContactsContract.Data.CONTACT_ID=?",
arrayOf(contractId)
)
5.删除联系人
- 根据姓名删除联系人
val ret = contentResolver.delete(
ContactsContract.RawContacts.CONTENT_URI,
CommonDataKinds.Phone.DISPLAY_NAME + "=?",
arrayOf("some_name")
)
if(ret>0)
Toast.makeText(this,"删除成功", Toast.LENGTH_SHORT).show()
else
Toast.makeText(this, "删除失败", Toast.LENGTH_SHORT).show()
- 根据手机号删除联系人
val contact_id = getContactIdByPhone(1111)
contentResolver.delete(RawContacts.CONTENT_URI,CommonDataKinds.Phone.CONTACT_ID+"=?", arrayOf(contact_id));
6.读取收件箱所有短信
字段 | 说明 |
---|---|
address | 收件人地址,即手机号,如+8613811810000 |
person | 人物 |
date | 日期,long型,如1256539465022,可以对日期显示格式进行设置 |
protocol | 协议0 :SMS_RPOTO短信,1:MMS_PROTO彩信 |
read | 是否阅读0:未读,1:已读 |
type | 短信类型1: 接收到的短信,2:发出的短信 |
body | 短信具体内容 |
需要动态获取权限
<uses-permission android:name="android.permission.READ_SMS"/>
private fun getMessage()
val uri = Uri.parse("content://sms/")
val resolver = contentResolver
//查询短信的 发件人地址 日期 短信类型 短信具体内容
val cursor = resolver.query(uri, arrayOf("address", "address", "type", "body"), null, null, null)?:return
while (cursor.moveToNext())
val address = cursor.getString(0)
val data = cursor.getString(1)
val type = cursor.getString(2)
val body = cursor.getString(3)
Log.e("ContentProvider","收件人 $address")
Log.e("ContentProvider","类型时间 [$type]:$data")
Log.e("ContentProvider","短信内容 $body")
Log.e("ContentProvider","-----------------------------")
cursor.close() //关闭游标!!
短信相关的其它操作uri
content://sms/ 所有短信
content://sms/inbox 收件箱
content://sms/sent 已发送
content://sms/draft 草稿
content://sms/outbox 发件箱
content://sms/failed 发送失败
content://sms/queued 待发送列表
以上是关于五ContentProvider权限动态申请 通讯录增删改查的主要内容,如果未能解决你的问题,请参考以下文章
Android 应用开发动态权限管理示例 ( 使用原生代码实现 | 申请权限 | 判定权限申请结果 | 判定 “ 不再询问 “ 情况 )