Kotlin终章:动态权限申请

1. 联系人管理

1. 清单文件添加权限

AndroidManifest.xml中添加权限

<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />

2. 创建Activity

1. 创建xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <Button
        android:id="@+id/get_contact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="查询联系人"/>
    <Button
        android:id="@+id/update_contact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="更新联系人"/>
    <Button
        android:id="@+id/insert_contact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="插入联系人"/>
    <Button
        android:id="@+id/del_contact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="删除联系人"/>
</LinearLayout>

2. 创建Activity

  1. 创建Activity文件
package com.example.myapplication.prodiver

import android.content.ContentUris
import android.content.ContentValues
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.provider.ContactsContract
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.example.myapplication.R
import com.example.myapplication.utils.ToastUtil
import kotlinx.android.synthetic.main.activity_content_provider.*

class TestContentProviderActivity: AppCompatActivity() {
   
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 绑定xml文件
        setContentView(R.layout.activity_content_provider)
    }
    
}
  1. 清单文件中添加注册
<application>
	<activity android:name=".prodiver.TestContentProviderActivity">
</application>
  1. 添加按钮点击事件
class TestContentProviderActivity: AppCompatActivity() {
   
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 绑定xml文件
        setContentView(R.layout.activity_content_provider)
        initView()
    }
    
    private fun initView(){
        get_contact.setOnClickListener {
            getContacts()
        }

        update_contact.setOnClickListener {
            updateContacts()
        }

        insert_contact.setOnClickListener {
            addContacts()
        }

        del_contact.setOnClickListener {
            delContacts()
        }
    }
    
    private fun getContacts(){}
    private fun updateContacts(){}
    private fun addContacts(){}
    private fun delContacts(){}
}
  1. 添加权限认证操作
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_content_provider)
    initView()
    var readFlag = ActivityCompat.checkSelfPermission(this, readContacts) != PackageManager.PERMISSION_GRANTED
    var writeFlag = ActivityCompat.checkSelfPermission(this, writeContacts) != PackageManager.PERMISSION_GRANTED
    if(readFlag && writeFlag){

        if(ActivityCompat.shouldShowRequestPermissionRationale(this,readContacts)){
            //引导用户打开读取联系人权限
        }

        ActivityCompat.requestPermissions(this,
                                          arrayOf(readContacts,writeContacts),
                                          100
                                         )

    }else{
        //getContacts()
    }
}
  1. 添加权限申请回调
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    // 这个需要与上边的 ActivityCompat.requestPermissions 最后一个参数一致
    if(requestCode == 100){
        if(grantResults.contains(PackageManager.PERMISSION_GRANTED)){
            if(permissions.contains(readContacts) && permissions.contains(writeContacts)){
                ToastUtil.makeTextShowLong(this,"获取读写通讯录权限成功")
            }else{

                if(permissions.contains(readContacts)){
                    ToastUtil.makeTextShowLong(this,"获取读取通讯录权限成功")
                }else{
                    ToastUtil.makeTextShowLong(this,"获取读取通讯录权限失败")
                }

                if(permissions.contains(writeContacts)){
                    ToastUtil.makeTextShowLong(this,"获取写入通讯录权限成功")
                }else{
                    ToastUtil.makeTextShowLong(this,"获取写入通讯录权限失败")
                }
            }
        }else{
            ToastUtil.makeTextShowLong(this,"用户拒绝授权")
        }

    }
}

3. 查询联系人

表名说明
content://com.android.contacts/data/phones读取联系人的表的名字
字段说明
display_name用户名
data1手机号
  • 代码
private fun getContacts(){
    ToastUtil.makeTextShowLong(this,"获取联系人")
    var contentResolver = contentResolver
    val uri =Uri.parse("content://com.android.contacts/data/phones")
    var query = contentResolver.query(uri, null, null, null, null)!!
    while(query.moveToNext()){
        // 这里需要传入下标
        var name = query.getString(
            // 这里的参数是string类型的,如果嫌变量名太长可以直接写字符串
            query.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME) ?: 0
        )
        var phone = query.getString(
            query.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER) ?: 0
        )
        ToastUtil.makeTextShowLong(this,"$name,$phone")
        Log.e("$this","$name,$phone")
    }
    query.close()
}
  • 运行结果
姓名:china unicom
号码:10010
======================
姓名:zhang san
号码:10086

4. 插入联系人

插入联系人需要有写入权限

<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
表名说明
content://com.android.contacts/data/data插入联系人的表的名字
content://com.android.contacts/data/raw_contacts插入联系人的原始表的名字
  • 代码
private fun addContacts() {
    val values = ContentValues()
    /*
         * 首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获得系统返回的rawContactId
         * 这时后面插入data表的数据,才能使插入的联系人在通讯录里面可见
         */
    val rawContactUri: Uri = contentResolver!!.insert(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, StructuredName.CONTENT_ITEM_TYPE) //内容类型
    values.put(StructuredName.GIVEN_NAME, "李四")
    contentResolver.insert(ContactsContract.Data.CONTENT_URI, values)

    //往data表里写入电话数据
    values.clear()
    values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
    values.put(ContactsContract.Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
    values.put(Phone.NUMBER, "13921009789")
    values.put(Phone.TYPE, Phone.TYPE_MOBILE)
    contentResolver.insert(ContactsContract.Data.CONTENT_URI, values)

    //往data表里写入Email的数据
    values.clear()
    values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
    values.put(ContactsContract.Data.MIMETYPE, Email.CONTENT_ITEM_TYPE)
    values.put(Email.DATA, "lisi@qq.com")
    values.put(Email.TYPE, Email.TYPE_WORK)
    contentResolver
    .insert(ContactsContract.Data.CONTENT_URI, values)
}

5. 更新联系人

  1. 首先需要获取联系人的contact_id
private fun getContentIdPyPhone(phone: Long): String?{
    val uri =Uri.parse("content://com.android.contacts/data/phones/filter/$phone")
    val cursor = contentResolver.query(
        uri,
        arrayOf(ContactsContract.Data.CONTACT_ID),
        null,
        null,
        null
    )!!
    if (cursor.moveToFirst()) {
        return cursor.getString(0)
    }
    return ""
}
  1. 更新联系人信息
private fun updateContacts(){
    ToastUtil.makeTextShowLong(this,"编辑联系人")
    var idPyPhone = getContentIdPyPhone(17663702529L)
    if(idPyPhone == null){
        ToastUtil.makeTextShowShort(this,"联系人不存在")
    }
    val values = ContentValues()
    values.put(ContactsContract.Data.MIMETYPE,
               ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
              ) //内容类型
    values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, "lisi")
    contentResolver.update(
        Uri.parse("content://com.android.contacts/data"),
        values,
        "${ContactsContract.Data.CONTACT_ID}=?",
        arrayOf(idPyPhone)
    )
}

6. 删除联系人

  • 根据姓名删除联系人
contentResolver.delete(RawContacts.CONTENT_URI,CommonDataKinds.Phone.DISPLAY_NAME+"=?", arrayOf("test"));
  • 根据手机号删除联系人
val contact_id = getContactIdByPhone(18854285999L)

contentResolver.delete(RawContacts.CONTENT_URI,
                       CommonDataKinds.Phone.CONTACT_ID+"=?", 		
                       arrayOf(contact_id));

2. 读取短信

短信相关的其它操作uri

content://sms/ 所有短信

content://sms/inbox 收件箱

content://sms/sent 已发送

content://sms/draft 草稿

content://sms/outbox 发件箱

content://sms/failed 发送失败

content://sms/queued 待发送列表

字段说明
address发件人地址,即手机号,如+8613811810000
person发件人地址,即手机号,如+8613811810000
date日期,long型,如1256539465022,可以对日期显示格式进行设置
protocol协议0 :SMS_RPOTO短信,1:MMS_PROTO彩信
read是否阅读0:未读,1:已读
type短信类型1: 接收到的短信,2:发出的短信
body短信具体内容
  1. 添加读取短信权限
<uses-permission android:name="android.permission.READ_SMS" />
  1. 修改资源文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <Button
        android:id="@+id/get_contact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="查询联系人"/>
    <Button
        android:id="@+id/update_contact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="更新联系人"/>
    <Button
        android:id="@+id/insert_contact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="插入联系人"/>
    <Button
        android:id="@+id/del_contact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="删除联系人"/>
    <Button
        android:id="@+id/getSms"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="读取短信"/>
</LinearLayout>
  1. 修改activity
package com.example.myapplication.prodiver

import android.content.ContentUris
import android.content.ContentValues
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.provider.ContactsContract
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.example.myapplication.R
import com.example.myapplication.utils.ToastUtil
import kotlinx.android.synthetic.main.activity_content_provider.*

class TestContentProviderActivity: AppCompatActivity() {
    private var tag = "TestContentProviderActivity"
    private var readContacts = android.Manifest.permission.READ_CONTACTS
    private var writeContacts = android.Manifest.permission.WRITE_CONTACTS
    private var readSms = android.Manifest.permission.READ_SMS
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_content_provider)
        initView()
        var readFlag = ActivityCompat.checkSelfPermission(this, readContacts) != PackageManager.PERMISSION_GRANTED
        var writeFlag = ActivityCompat.checkSelfPermission(this, writeContacts) != PackageManager.PERMISSION_GRANTED
        var readSmsFlag = ActivityCompat.checkSelfPermission(this, readSms) != PackageManager.PERMISSION_GRANTED
        if(readFlag && writeFlag && readSmsFlag){

            if(ActivityCompat.shouldShowRequestPermissionRationale(this,readContacts)){
                //引导用户打开读取联系人权限
            }

            ActivityCompat.requestPermissions(this,
                arrayOf(readContacts,writeContacts),
                100
            )

        }else{
            //getContacts()
        }
    }
    private fun initView(){
        get_contact.setOnClickListener {
            getContacts()
        }

        update_contact.setOnClickListener {
            updateContacts()
        }

        insert_contact.setOnClickListener {
            addContacts()
        }

        del_contact.setOnClickListener {
            delContacts()
        }
        getSms.setOnClickListener {
            getSms()
        }
    }

    private fun getSms(){

        var uri = Uri.parse("content://sms/")
        var resolver = contentResolver
        var query = resolver.query(
            uri,
            arrayOf("address", "date", "type", "body"),
            null, null, null
        )!!
        while(query.moveToNext()){
            val address: String = query.getString(0)
            val date: String = query.getString(1)
            val type: String = query.getString(2)
            val body: String = query.getString(3)
            ToastUtil.makeTextShowShort(this,"$address $date $type $body")
        }


    }

    private fun getContacts(){
        ToastUtil.makeTextShowLong(this,"获取联系人")
        var contentResolver = contentResolver
        val uri =Uri.parse("content://com.android.contacts/data/phones")
        var query = contentResolver.query(uri, null, null, null, null)!!
        while(query.moveToNext()){
            var name = query.getString(
                query.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME) ?: 0
            )
            var phone = query.getString(
                query.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER) ?: 0
            )
            ToastUtil.makeTextShowLong(this,"$name,$phone")
            Log.e("$this","$name,$phone")
        }
        query.close()
    }
    private fun updateContacts(){
        ToastUtil.makeTextShowLong(this,"编辑联系人")
        var idPyPhone = getContentIdPyPhone(17663702529L)
        if(idPyPhone == null){
            ToastUtil.makeTextShowShort(this,"联系人不存在")
        }
        val values = ContentValues()
        values.put(ContactsContract.Data.MIMETYPE,
            ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
        ) //内容类型
        values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, "lisi")
        contentResolver.update(
            Uri.parse("content://com.android.contacts/data"),
            values,
            "${ContactsContract.Data.CONTACT_ID}=?",
            arrayOf(idPyPhone)
        )
    }
    private fun addContacts(){
        ToastUtil.makeTextShowLong(this,"新增联系人")
        var contentResolver = contentResolver
        var values = ContentValues()
        var insertUri =
            contentResolver.insert(ContactsContract.RawContacts.CONTENT_URI, values)!!
        var rawContactId = ContentUris.parseId(insertUri)
        //往data表里写入姓名数据
        values.clear()
        values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) //内容类型
        values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, "李四")
        contentResolver.insert(ContactsContract.Data.CONTENT_URI, values)

        //往data表里写入电话数据
        values.clear()
        values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, "13921009789")
        values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
        contentResolver.insert(ContactsContract.Data.CONTENT_URI, values)

        //往data表里写入Email的数据
        values.clear()
        values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
        values.put(ContactsContract.CommonDataKinds.Email.DATA, "lisi@qq.com")
        values.put(ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK)
        contentResolver
            .insert(ContactsContract.Data.CONTENT_URI, values)
    }

    private fun delContacts(){
        ToastUtil.makeTextShowLong(this,"删除联系人")
        contentResolver.delete(ContactsContract.RawContacts.CONTENT_URI,
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+"=?", arrayOf("李四"));
    }

    private fun getContentIdPyPhone(phone: Long): String?{
        val uri =Uri.parse("content://com.android.contacts/data/phones/filter/$phone")
        val cursor = contentResolver.query(
            uri,
            arrayOf(ContactsContract.Data.CONTACT_ID),
            null,
            null,
            null
        )!!
        if (cursor.moveToFirst()) {
            return cursor.getString(0)
        }
        return ""
    }


    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        /*if(requestCode == 100 &&
            permissions.contains(readContacts) &&
            grantResults.contains(PackageManager.PERMISSION_GRANTED)){
            getContacts()
        }else{
            ToastUtil.makeTextShowLong(this,"读取通讯录权限被拒绝")
        }*/

        if(requestCode == 100){
            if(grantResults.contains(PackageManager.PERMISSION_GRANTED)){
                if(permissions.contains(readContacts) &&
                    permissions.contains(writeContacts) &&
                    permissions.contains(readSms)){
                    ToastUtil.makeTextShowLong(this,"获取读写通讯录/ 读取短信 权限成功")
                }else{

                    if(permissions.contains(readContacts)){
                        ToastUtil.makeTextShowLong(this,"获取读取通讯录权限成功")
                    }else{
                        ToastUtil.makeTextShowLong(this,"获取读取通讯录权限失败")
                    }

                    if(permissions.contains(writeContacts)){
                        ToastUtil.makeTextShowLong(this,"获取写入通讯录权限成功")
                    }else{
                        ToastUtil.makeTextShowLong(this,"获取写入通讯录权限失败")
                    }

                    if(permissions.contains(readSms)){
                        ToastUtil.makeTextShowLong(this,"获取读取短信权限成功")
                    }else{
                        ToastUtil.makeTextShowLong(this,"获取读取短信权限失败")
                    }

                }
            }else{
                ToastUtil.makeTextShowLong(this,"用户拒绝授权")
            }

        }
    }
}

3. 打包App

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值