Kotlin和Android开发的新手,在更新了一些库之后,我以前获取联系方式的工作方法出现了一些问题,所以我决定尝试在https://developer.android.com/training/basics/intents/result而不是调试我的"遗留"代码。在这样做的过程中,如果不需要READ_CONTACTS权限,我将无法再让它发挥作用,所以我希望有人能用线索棒打我,帮助我改变新方法,以实现以前的方法。
谢谢。
以前的方法
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
fab.setOnClickListener {
val intent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI).also {
it.type = ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE
startActivityForResult(it, 1)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == 1 && resultCode == RESULT_OK) {
val projection = arrayOf(
ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER
)
GlobalScope.launch {
data?.data?.also { contactUri ->
context?.contentResolver?.query(contactUri, projection, null, null, null)?.apply {
moveToFirst()
//val id = viewModel.addPerson(DefaultPerson(getString(0), getString(1), getString(2)))
close()
}
}
}
}
}
新方法
private val getPerson = registerForActivityResult(PickContact()) {
val projection = arrayOf(
ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER
)
context?.contentResolver?.query(it!!.toUri(), projection, null, null, null)?.apply {
moveToFirst()
//val id = viewModel.addPerson(DefaultPerson(getString(0), getString(1), getString(2)))
close()
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
fab.setOnClickListener {
getPerson.launch(0)
}
}
class PickContact : ActivityResultContract<Int, String?>() {
override fun createIntent(context: Context, input: Int?) =
Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI).also {
it.type = ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE
}
override fun parseResult(resultCode: Int, intent: Intent?): String? {
return if (resultCode == RESULT_OK) intent?.toUri(0) else null
}
}
看起来我把与Uri有关的事情搞砸了。与此相关的以下更改解决了问题:
val getPerson = registerForActivityResult(PickContact()) {
it?.also { contactUri ->
val projection = arrayOf(
ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER
)
context?.contentResolver?.query(contactUri, projection, null, null, null)?.apply {
moveToFirst()
//val id = viewModel.addPerson(DefaultPerson(getString(0), getString(1), getString(2)))
close()
}
}
}
class PickContact : ActivityResultContract<Int, Uri?>() {
override fun createIntent(context: Context, input: Int?) =
Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI).also {
it.type = ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE
}
override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
return if (resultCode == RESULT_OK) intent?.data else null
}
}