I'm trying to get all messages from the user's phone, user number, text messages are retrieved successfully. But the problem is how can I get the UserName of the message sender saved in the user mobile device.
I'm getting the error Caused by: java.lang.NullPointerException: cur.getString(cur.getColumnIndex("person")) must not be null
Here is the method to get user SMS.
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")) // error in this line occurs
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
}
How can I solve this issue?
Related
This question already has answers here:
Drop "is" prefix for Firebase Firestore fields for Boolean Values
(2 answers)
Prevent firebase from taking the method name as variable in Firebase
(2 answers)
Closed 5 months ago.
I have multiple data classes and all upload fine to Firebase Realtime database except for this one key "isCompleted" gets changed to "completed" in the database.
My data class:
data class MaintenanceLog(
val isCompleted: Boolean? = null,
val brand: String? = null,
val clientCode: String? = null,
val dateOfSubmission: Double? = null,
val details: String? = null,
val equipmentID: String? = null,
val id: String? = null,
val model: String? = null,
val name: String? = null,
val photosArray: List<String>? = null,
val refNum: String? = null,
val restaurantID: String? = null,
var hidden: Boolean? = null,
val userSelectedDate: Double? = null,
val wasFutureMaintCreated: Boolean? = null,
val workLogRef: String? = null,
val contractorCode: String? = null,
val isCalendarEvent: Boolean? = null,
val calendarEvent_venueName: String? = null,
val createdBy: String? = null
)
Implementation:
val demoLog = MaintenanceLog(
isCompleted = true,
id = "DemoLog22222",
equipmentID = "demo_equipID_123456",
refNum = "DemoRefNum_123456",
dateOfSubmission = APSDate.getCurrentDatabaseFormattedTime(),
details = "Maintenance Log created from Work Log - Demo Description",
photosArray = null,
workLogRef = "DemoRefNum_123456",
createdBy = "Demo User",
clientCode = "Demo Client",
restaurantID = "Demo Restaurant",
brand = "Demo Brand",
model = "Demo Model",
name = "Demo User",
userSelectedDate = APSDate.dateFromComponents(timeIn_Year, timeIn_Month, timeIn_Day, timeIn_Hour, timeIn_Minute),
wasFutureMaintCreated = false)
dbRef.child(FirebaseLocations.MAINTENANCE_RECORDS.code).child("111_demo_path").setValue(demoLog)
The demo log when setting the value:
And the firebase value:
Why is "isCompleted" getting changed to "completed" when uploaded to the database?
I'm working on a firebase chatting app. I want to maintain chats between two different users for this I'm creating a parent node as +923478302658#Chat and within it, a child node as +923478302658-+923065015216 within it messages for both participants.
Here is my Chat Model:
class AllChatsModel {
var chatID: String? = null
var chatStarterName: String? = null
var chatRecieverName: String? = null
var chatStartTD: String? = null
var chatLastMessage: String? = null
var chatLastMsgTime: String? = null
var chatHeadActive: Boolean? = null
var chatMessages: ArrayList<MessageModel>? = null
}
And here is the function to send a message:
private fun sendMessage(message: String) {
val dateFormat = SimpleDateFormat("dd MMMM, yyyy 'at' HH:mm aaa")
val calendar = Calendar.getInstance()
val currentTime: String = dateFormat.format(calendar.time)
val chatID = databaseReference!!.push().key
val chatModel = AllChatsModel()
chatModel.chatStarterName = (sharedPreference?.userName)
chatModel.chatRecieverName = signUpEntity?.userUID
chatModel.chatStartTD = currentTime
chatModel.chatLastMessage = message
chatModel.chatLastMsgTime = currentTime
val chatMessagesList: ArrayList<MessageModel>? = chatModel?.chatMessages // debugs gives null here
val messageID = databaseReference!!.push().key
val messageModel = MessageModel()
messageModel.messageID = messageID
messageModel.messageText = message
messageModel.messageTime = currentTime
messageModel.msgSenderID = FirebaseAuth.getInstance().uid
messageModel.msgSenderName = (sharedPreference?.userName)
messageModel.msgSenderNo = (currentUserNo)
messageModel.msgReceiverID = signUpEntity?.userUID
messageModel.msgReceiverName = signUpEntity?.userName
messageModel.msgReceiverNo = signUpEntity?.userPhone
chatMessagesList?.add(messageModel) // here chatMessagesList is null
chatModel.chatMessages = chatMessagesList
FirebaseDatabase.getInstance().reference.child("${currentUserNo}#Chat")
.child("${currentUserNo}-${signUpEntity?.userPhone}")
.child("ChatMessages").setValue(chatModel)
txtInputMsg.setText("")
}
I want to get the firebase nodes structure like this but the app crashes. Why I'm not getting the data like that in the attached pic.
[1]: https://i.stack.imgur.com/QOW8c.png
I guess there is an error in how you define val chatMessagesList variable in sendMessage() function. Try to fix it to:
val chatMessagesList: ArrayList<MessageModel> = chatModel?.chatMessages ?: ArrayList<MessageModel>()
Using an Elvis operator ?: we guarantee that chatMessagesList variable won't be null.
When you write this code:
val chatMessagesList: ArrayList<MessageModel>? = chatModel?.chatMessages // debugs gives null here
chatModel?.chatMessages property isn't created yet, so it is null.
Just replace it with the next line and it will work:
val chatMessagesList: ArrayList<MessageModel> = chatModel?.chatMessages ?: ArrayList<MessageModel>()
Or you can just write:
val chatMessagesList = ArrayList<MessageModel>()
because you create a new object of AllChatsModel class in sendMessage() function, that's why chatModel?.chatMessages will always be null until it is initialized.
I've got the following code to retrieve a contact list with Name + PhoneNumber:
#SuppressLint("Range")
fun getNamePhoneDetails(): ArrayList<List<String>>? {
val names = ArrayList<List<String>>()
val cr = contentResolver
val cur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
null, null, null)
if (cur!!.count > 0) {
while (cur.moveToNext()) {
val id = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NAME_RAW_CONTACT_ID))
val name = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
val number = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
names.add(listOf(id, name, number))
}
}
return names
}
The output is correct once no contact has two phone numbers. However once any contact has two phone numbers I get the contact twice. It has the same id and name, but a different phone number. How can I make it so that the returned list does not have a contact twice but all phone numbers inside a list?
Something like
[1, Name Name, [phonenumber1, phonenumber2]],[2, Name Name, [phonenumber1]]
Then I could just iterate through the phonenumberlist and have all numbers as valid strings.
You should rather create a POJO Object and than assign the data into it and return a list of that POJO Object and then you can make use of distinct extension on the list to get a filtered result they way you want it .
This is how you can achieve what you want :
Create a POJO Object :
data class Contact(
val id : String ,
val name : String,
val number : String)
And then when retrieveing the data you can do the following :
#SuppressLint("Range")
fun getNamePhoneDetails(): MutableList<Contact>? {
val names = MutableList<Contact>()
val cr = contentResolver
val cur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
null, null, null)
if (cur!!.count > 0) {
while (cur.moveToNext()) {
val id = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NAME_RAW_CONTACT_ID))
val name = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
val number = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
names.add(Contact(id , name , number))
}
}
return names
}
And then while retreiving the data you need to just filter the list in the following manner :
val list = getNamePhoneDetails()
list.distinctBy { it.number }.forEach { println(it) }
I want to fetch a list of local contacts with an anniversary date set.
I'm doing the following:
object WithAnniversary {
const val INDEX_CONTACT_ID = 0
const val INDEX_CONTACT_NAME = 1
const val INDEX_CONTACT_ANNIVERSARY = 2
const val INDEX_CONTACT_PHOTO = 3
val PROJECTION = arrayOf(
CommonDataKinds.Event.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME,
CommonDataKinds.Event.START_DATE,
CommonDataKinds.Phone.PHOTO_URI
)
const val WHERE = "${ContactsContract.Data.MIMETYPE} = ? AND " +
"${CommonDataKinds.Event.TYPE} = " +
"${CommonDataKinds.Event.TYPE_ANNIVERSARY}"
val SELECTION = arrayOf(CommonDataKinds.Event.CONTENT_ITEM_TYPE)
val SORT_ORDER: String? = null
}
#Throws(Exception::class)
fun obtainContactsWithAnniversaries(): List<Contact> {
val list = mutableListOf<Contact>()
val cursor = context.contentResolver.query(
ContactsContract.Data.CONTENT_URI,
WithAnniversary.PROJECTION,
WithAnniversary.WHERE,
WithAnniversary.SELECTION,
WithAnniversary.SORT_ORDER
)
if (cursor != null) {
while (cursor.moveToNext()) {
val id = cursor.getLong(WithAnniversary.INDEX_CONTACT_ID)
val name = cursor.getString(WithAnniversary.INDEX_CONTACT_NAME)
val date = cursor.getString(WithAnniversary.INDEX_CONTACT_ANNIVERSARY)
val avatarUri = cursor.getString(WithAnniversary.INDEX_CONTACT_PHOTO)
try {
val contact = contactFactory.create(id.toString(), name, null, date, avatarUri)
list.add(contact)
} catch (e: Exception) {
Log.d(TAG, "Could not parse contact with name: $name")
}
}
cursor.close()
return list.sorted()
} else {
throw Exception("Unable to retrieve contacts, returned cursor is null")
}
}
I use the exact same process for retrieving contacts with birthday dates, but using TYPE_BIRTHDAY instead of TYPE_ANNIVERSARY, but for some reason this doesn't work for anniversaries.
I have checked my local contact list and I have some contacts with birthdays and anniversaries. I can retrieve a list with contacts with birthdays but the list of contacts with anniversaries is empty.
Any help will be appreciated.
I assume the issue is with the conversion of the cursor row to your custom Contact class.
When I replace that part with just a log your code works for me:
...
while (cursor.moveToNext()) {
val id = cursor.getLong(WithAnniversary.INDEX_CONTACT_ID)
val name = cursor.getString(WithAnniversary.INDEX_CONTACT_NAME)
val date = cursor.getString(WithAnniversary.INDEX_CONTACT_ANNIVERSARY)
val avatarUri = cursor.getString(WithAnniversary.INDEX_CONTACT_PHOTO)
Log.d("TEMP", "contact $id $name $date $avatarUri")
}
...
Log:
D/TEMP: contact 98014 Test1 1979-10-06 content://com.android.contacts/contacts/98014/photo
contact 4603 test 1990-07-22 content://com.android.contacts/contacts/4603/photo
contact 98341 Voice Mail 2013-11-06 null
I'm trying to get a list of SMS conversations on Android. I made this Kotlin code:
kotlin
val threads = contentResolver.query(Telephony.Threads.CONTENT_URI, null, null, null, Telephony.Threads.DATE)
This throws this error:
java.lang.RuntimeException: java.lang.IllegalArgumentException: Invalid column null
I don't think am querying it the right way. What can I do to fix it? Thank you in advance.
To fetch an Inbox message try this code:
First, create a Model class of messages name Message
data class Message (
var messageNumber:String?=null,
var messageContent:String?=null
)
Then fetch inbox message list like this:
private fun fetchInboxMsg(): ArrayList<Message>? {
val messageList = ArrayList<Message>()
val uriSms: Uri = Uri.parse("content://sms")
val cursor = contentResolver.query(
uriSms, arrayOf("DISTINCT address", "body"), //DISTINCT
"address IS NOT NULL) GROUP BY (address", //GROUP BY
null, null
)
if (cursor!!.count > 0) {
cursor.moveToFirst()
for (i in 0 until cursor.count) {
val number: String? = cursor.getString(cursor.getColumnIndex("address"))
val content: String? = cursor.getString(cursor.getColumnIndex("body"))
val message = Message(number, content)
messageList.add(message)
cursor.moveToNext()
}
}
cursor.close()
return messageList
}
Don't forget to provide permission READ_SMS