乐趣区

关于android:Android-Kotlin语言学习第二课权限申请和ContentProvider简单使用

一:增加一个展现数据的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <ListView
        android:id="@+id/contactsView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

二:增加 BaseActivity

abstract class BaseActivity : AppCompatActivity() {
    /**
     * kotlin 容许一个类继承另一个类
     * kotlin 所有的类都继承自 Any 类(Any 不是 java.lang.Object)* Any 类是所有类的超类,对于没有超类型申明的类是默认超类
     * Kotlin 规定一个类能够给继承,必须应用 open 关键字润饰
     * */

    /**
     * 抽象类:关键字为 abstract
     * 形象函数:abstract fun initView()
     * 形象属性:abstract var name:String */

    /**
     * 变量能够定义为可变 (var) 和不可变(val)* 常量定义:val 相当于被 final 润饰  var 相当于可变非 final 润饰
     * 等价于 Java:public static final String TAG=BaseActivity.class.getSimpleName()*/
    // 定义标记
    open val TAG: String = this.javaClass.simpleName

    // 初始化布局 View
    abstract fun initView()

    // 初始化数据
    abstract fun initData()

    // 初始化获取布局 id, 带返回值的形象办法
    abstract fun getLayoutId(): Int

    /**
     * 语法定义
     * fun 办法名(参数名:参数类型):返回值类型{
     *
     * return 返回值
     *
     * }
     *
     * 无返回值能够应用 Unit 代替返回值类型 ? 代表可空
     * Kotlin 是 null 平安的语言 Byte ,Short,Int ,Long 型的变量都是不能承受 null 值,如果要存储 null 值须要应用 Byte?,Short?,Int?,Long?
     *
     *  override fun onCreate(savedInstanceState: Bundle?):Unit{
     *
     *  }
     **/
    override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
        setContentView(getLayoutId())

        initView()
        initData()}

    override fun onDestroy() {super.onDestroy()
    }
}

三:定义 FourActivity, 实现权限受权和联系人数据 ContentResolver 解析过程间通信

class FourActivity : BaseActivity() {
    private val CONTACT_REQUEST_CODE = 1

    //ListView 布局文件
    lateinit var contactsView: ListView

    // 汇合数据
    private val contactsList = ArrayList<String>()

    // 适配器
    private lateinit var adapter: ArrayAdapter<String>
    override fun initView() {contactsView = findViewById<ListView>(R.id.contactsView)
        adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, contactsList)
        contactsView.adapter = adapter
        // 权限查看
        checkP(this)

    }

    private fun checkP(context: Context) {
        // 查看权限是否受权,这个查看的权限是读取手机联系人
        if (ContextCompat.checkSelfPermission(
                context,
                android.Manifest.permission.READ_CONTACTS
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            // 没有受权,申请权限受权
            // 参数类型,Activity, 权限组,申请码
            ActivityCompat.requestPermissions(
                context as Activity,
                arrayOf(android.Manifest.permission.READ_CONTACTS),
                CONTACT_REQUEST_CODE
            )
        } else {
            // 受权了
            readContacts()}

    }

    /** 权限申请点击容许和回绝都会回调 onRequestPermissionsResult 办法 */

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            CONTACT_REQUEST_CODE -> {if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 容许受权
                    readContacts()} else {
                    // 回绝受权
                    Toast.makeText(this, "You denied the Permission", Toast.LENGTH_SHORT).show()}
            }
        }
    }

    /** 读取联系人操作,应用 ContentProvider*/

    private fun readContacts() {
        // 查问联系人数据
        contentResolver.query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null,
            null,
            null,
            null
        )?.apply {while (moveToNext()) {
                // 获取联系人姓名
                val displayName =
                    getString(getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
                // 获取联系人手机号
                val number =
                    getString(getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                contactsList.add("$displayName\n$number")
                adapter.notifyDataSetChanged()
                /**
                 * 剖析 log:android.database.StaleDataException: Attempted to access a cursor after it has been
                 * 然而同样的代码在 android2.2 上边没有产生,在 android3.0 上边产生了,剖析起因在于
                android4.0 的 managedCursor /managedQuery 会主动的 close 一个 cursor,然而咱们又手动的敞开了一次,所以导致了这个问题,解决方案是在 4.0 的代码去掉 close 这个操作。*/

                if (Integer.parseInt(Build.VERSION.SDK) < 11) {close()
                }


            }
        }

    }

    override fun initData() {}

    override fun getLayoutId(): Int {return R.layout.activity_four}
}

四:增加权限在 AndroidManifest

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

退出移动版