安卓读取设备短信时如何获取发件人姓名并解决空指针问题
错误根因
person字段对应短信发件人在通讯录中的联系人ID,仅当发件人号码已存入设备通讯录时该字段有值,未存入时会返回null。你将可能为null的返回值直接赋值给Kotlin非空类型String,触发了空指针异常。
修复方案
基础修复(空安全处理)
直接对person字段做空兼容处理,无值时填入默认值即可,修改代码如下:
fun getSMS() { msgArrayList = ArrayList() msgArrayList?.clear() val uriSMSURI: Uri = Uri.parse("content://sms/inbox") val cur: Cursor? = contentResolver.query(uriSMSURI, null, null, null, null) while (cur != null && cur.moveToNext()) { // 修改这行,做空安全处理 val person: String = cur.getString(cur.getColumnIndex("person")) ?: "未知联系人" val date: String = cur.getString(cur.getColumnIndex("date")) val address: String = cur.getString(cur.getColumnIndex("address")) val body: String = cur.getString(cur.getColumnIndexOrThrow("body")) val model = AllMessagesModel(address ,body,person,date) msgArrayList?.add(model) } cur?.close() allMsgAdapter = MessageAdapter(this, msgArrayList) val layoutManager = LinearLayoutManager(applicationContext, RecyclerView.VERTICAL, false) rvMessages!!.layoutManager = layoutManager rvMessages?.adapter = allMsgAdapter }
进阶修复(主动查询联系人姓名)
如果需要准确获取已存联系人的姓名,可以用获取到的address(手机号)主动去通讯录Provider中查询,步骤如下:
- 提前申请
android.permission.READ_CONTACTS运行时权限 - 新增查询联系人姓名的工具方法:
fun getContactNameByPhone(phoneNumber: String): String { val uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)) val projection = arrayOf(ContactsContract.PhoneLookup.DISPLAY_NAME) contentResolver.query(uri, projection, null, null, null)?.use { cursor -> if (cursor.moveToFirst()) { return cursor.getString(0) } } return "未知联系人" }
- 替换原来的person字段获取逻辑:
val address: String = cur.getString(cur.getColumnIndex("address")) // 用手机号主动查询姓名 val person: String = getContactNameByPhone(address)
内容的提问来源于stack exchange,提问作者Usama Hafeez Official
相关产品推荐
相关产品推荐

