一:添加一个展示数据的布局
<?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"/>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。