ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

五、ContentProvider权限动态申请 通讯录增删改查

2021-11-19 21:02:17  阅读:202  来源: 互联网

标签:CommonDataKinds val 联系人 改查 cursor values 通讯录 ContactsContract ContentProvider


五、ContentProvider相关

ContentProvider内容提供者: 负责数据存取,常用于APP进数据共享,跨进程数据存取等…比如读取相册,读取联系人,都是ContentProvider来实现的

  • **1.**我们想在自己的应用中访问别的应用,或者说一些ContentProvider暴露给我们的一些数据, 比如手机联系人,短信、相册等!我们想对这些数据进行读取或者修改,这就需要用到ContentProvider了!
  • **2.**我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用到ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!

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 待发送列表

标签:CommonDataKinds,val,联系人,改查,cursor,values,通讯录,ContactsContract,ContentProvider
来源: https://blog.csdn.net/white1148/article/details/121430848

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有