一:增加一个展现数据的布局
<?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"/>