sms.personId is different person from contacts.FindByName??? Please help.

bsnqt

Active Member
Licensed User
Longtime User
Dear experts,

Happy New Year to everyone.

Please help to look at my problem:

- I use PhoneStateListener to catch an incoming number (<-- successful)

- When there is an incoming call, I use the caller's number to search in the phone inbox ( <-- successful)

- If there is a received SMS in the inbox (sent by the caller that is making the call), I use the personID of this SMS to look back into the contacts list to find out the contact with same personID, using Contacts.GetById (<-- PROBLEM IS HERE, as the PersonId from SMS is not the same person in Contacts, having the same Id number)

- I checked the log and can see that with the same sms.personId (from the SMS sender?), it gives me a totally different person in the Contacts. They are 2 different persons. Why?

B4X:
'================================================
Dim SmsMessages1 As SmsMessages
Dim smsList As List
Dim myContacts As Contacts2

'================================================

Sub PSL2_onCallStateChanged (State As Int, incomingNumber As String)

   Dim mySms As Sms

   smsList = SmsMessages1.GetAllSince(DateTime.add(DateTime.Now, 0, 0, -90))
               
   incomingNumber = ParseRawPhone(incomingNumber) 

   For i = 0 To smsList.Size - 1
             
      mySms = smsList.Get(i)
            
      If mySms.Address.EndsWith(incomingNumber) Then
      
      Dim callerid As Int = mySms.PersonId

      Log(callerid)   ' <-- I know the Sms is from JOHN, here the callerid gives me id = 201

      ' ============= Check If the person with id 201 in the Contacts Is JOHN? ============ ' 
                  
      Dim callercontact As Contact
         
      callercontact = myContacts.GetById(callerid, True, False)
      
      Log(callercontact.DisplayName) ' <-- NO, in the contacts the person with Id 201 is totally different, 201 is giving MARY
      
      ' ============= So what is JOHN's Id in the contacts, I want to check it ============ ' 
         
      Dim mlist As List
            
      mlist = myContacts.FindByName("JOHN", True, True,False)
                  
      callercontact = mlist.Get(0)   ' <--- This gives me a totally different Id for JOHN, it it 210 (not 201)
                  
      End If
         
   Next
   
End Sub

Sub ParseRawPhone(s As String) As String
    Dim sb As StringBuilder
    sb.Initialize
    For i = 0 To s.Length - 1
     If IsNumber(s.CharAt(i)) Then sb.Append(s.CharAt(i))
    Next
       
    Return sb.ToString.SubString(4)
End Sub
 
Last edited:

bsnqt

Active Member
Licensed User
Longtime User
The Phone library will be updated for the next B4A version. It will allow you to customize the query string. It seems like you need to compare the id to a given field. I will help you once it is released.

Hi Erel, thank you very much for the support. In the mean time I will try to look for the workaround and if necessary I will ask for your assistance.

Best

bsnqt
 
Upvote 0

RichyK68

Active Member
Licensed User
Longtime User
Is there an update or resolution for this? I believe I'm having a related issue. When I use method GetByPersonId on SMSMessages to get the list of messages for that contact (the contact id is definitely correct, as I even added some notes to the contact to confirm) it returns 0 messages, despite there being hundreds for that contact.

Richard
 
Upvote 0

bsnqt

Active Member
Licensed User
Longtime User
Hi RichyK68 (and to those who have same problem):

I found out the reason why the PersonId in SMS is not the same person's id as in Contacts.

The personId in my example code above (mySms.PersonId) SHOULD BE actually the raw_contact_id in Contacts database. If you have a rooted phone (and root explorer), you can see it easily in /data/data/com.android.providers.contacts/databases/database2.db.

For getting the right Contact, just use the ContactsUtils like Erel said or you also can use ContentResovler (actually the same as ContactsUtils).
Make your search for the PersonId in the field "raw_contact_id" with the help of ContentResolver, you will find it out.

To add: the easier way is to look up for the name of the Contact using the address (phone number of sender :) )
 
Last edited:
Upvote 0

RichyK68

Active Member
Licensed User
Longtime User
My problem is that I've got the cuContact object via ContactUtils for the required contact, but using the Id of that contact along with an SmsMessages object and the GetByPersonId method returns a list of zero messages, when I know there are hundreds.

But obviously, I'm doing something wrong, so if you can enlighten me :)

Thanks,

Richard
 
Upvote 0

bsnqt

Active Member
Licensed User
Longtime User
Okay, look at this example:

I assume you have only one Contact with phone number "01234567890".
Based on what you described, first step is you will find the Id of this Contact using ContactUtils.
For example, here you find the Id of this Contact using the phone number:

B4X:
Sub FindContactId(phonenumber as String) As String
    Dim phoneList As List
    phoneList.Initialize
    phoneList = cu.FindContactsByPhone(phonenumber, False, False)   
    Dim c As cuContact
    c = phoneList.Get(0)
    Return c.id
End Sub

Now, after getting the Id of this Contact, you need to find out the so called Raw Contact Id by using this:

B4X:
Sub FindRawContactId(ContactId as String) As String

    Private phonesUri As Uri
    phonesUri.Parse("content://com.android.contacts/data/phones")
    Private cr As ContentResolver
    cr.Initialize("")
    Private phones As Cursor = cr.Query(phonesUri, Array As String("raw_contact_id","contact_id"),"contact_id =?", Array As String(ContactId), "")
    If phones.RowCount > 0 Then
        phones.Position = 0
        Return phones.GetString("raw_contact_id”)
    Else
        Return “”
    End If
    phones.Close
End Sub

Now, you use the received Raw Contact Id to search for messages in SmsMessages (using method GetByPersonId). I am sure that you can find out all related messages.

In summary, the id you have to use with GetByPersonId is the Raw Contact Id, not the Contact Id itself.

Please, keep me posted if it works (it should work, as I already tested :))

EDIT: Of course, the better way is to directly modify codes in ContactUtils to find the raw contact id right away using the phone number of contact (will be faster) but I don't have time to do that.
 
Last edited:
Upvote 0

RichyK68

Active Member
Licensed User
Longtime User
Here is the code I am using for testing:

Dim listOfContacts As List
listOfContacts.Initialize
' I have modified FindContactsByPhone to return the raw_contact_id instead of the contact_id
' (but to be honest both the contact_id and the raw_contact_id are the same value, in this case anyway)
listOfContacts = CU.FindContactsByPhone("**** *** ***", False, True) ' I put my mobile number in here
' at this point, there is only one contact in the list, which is myself, Richard
Dim thecontact As cuContact = listofcontacts.Get(0) ' get the contact
Dim sm As SmsMessages
Dim tList As List = sm.GetByPersonId(thecontact.id) ' get the messages for this contact

At this point, tList has a size of zero, when in fact I know I have lots of test messages against my contact in the database.

So I still can't figure out what is wrong here.

Richard

ps here is the modified FindContactsByPhone code from the ContactsUtils class:

Private Sub FindContactsIdFromData (Mime As String, DataColumn As String, Value As String, Operator As String, _
Exact As Boolean, VisibleOnly As Boolean) As List
If Not(Exact) Then
Operator = "LIKE"
Value = "%" & Value & "%"
End If
Dim selection As String = "mimetype = ? AND " & DataColumn & " " & Operator & " ? "
If VisibleOnly Then selection = selection & " AND in_visible_group = 1"
Dim crsr As Cursor = cr.Query(dataUri, Array As String("raw_contact_id", "display_name"), selection, _
Array As String(Mime, Value), "")
Dim res As List
res.Initialize
Dim m As Map
m.Initialize
For i = 0 To crsr.RowCount - 1
crsr.Position = i
Dim cu As cuContact
cu.Initialize
cu.Id = crsr.GetLong("raw_contact_id")
cu.DisplayName = crsr.GetString("display_name")
If m.ContainsKey(cu.Id) Then Continue
m.Put(cu.Id, Null)
res.Add(cu)
Next
crsr.Close
Return res
End Sub
 
Upvote 0

bsnqt

Active Member
Licensed User
Longtime User
Hi RichyK68: I forgot to tell you that please do not modify the codes in ContactUtils like the way you described about. For some unknown reasons (I did not have time to figure out why, when I have more time, I will make more tests...), but I also modified exactly as you did, it did not give a correct raw_contact_id.

Please do like that:
  • Keep original ContactUtils as it is (from Erel), find out the Contact Id using this original ContactUtils.
  • Then use the Sub I posted in my previous post to find out raw_contact_id (Sub "FindRawContactId"). I wrote this Sub because I had same error as yours (I modified the codes in ContactUtils to get the raw_contact_id faster, but I got the wrong raw contact id).
  • Finally, use that raw_contact_id (received from the Sub in second step) to search in SmsMessages.

Please, again, do exactly the steps I described above.
Note that raw_contact_id can be the same as Contact Id, but I see (in the database file) 90% of the cases they are not identical.

(Do use the code editor to post your codes, otherwise it is hard to read)
 
Last edited:
Upvote 0

RichyK68

Active Member
Licensed User
Longtime User
My code is now:

Dim contactid As String = findcontactid("**** *** ***") ' my number goes here
Dim rawid As String = FindRawContactId(contactid)
Dim sm As SmsMessages
Dim tList As List
tList.Initialize
tList = sm.GetByPersonId(rawid)

and I've reverted ContactsUtils back to Erel's version, and added your two subroutines. Using my number I get the same raw_contact_id as contact_id and no messages, and using a different number I get a raw_contact_id that is different to the contact_id but I still get zero messages. I've even tried initializing the list, but I didn't think that was necessary anyway.

Still no luck :(

Richard

PS maybe it's another damned Galaxy S4 trait
 
Upvote 0

bsnqt

Active Member
Licensed User
Longtime User
Hi Richard,

I don't know how to help you now :(
I did test and it works for my case. At least with Sony Xperia S (4.1.2) and Samsung Note II.
I used the raw contact id and it works well. The Contact I tested has Contact Id = 285 and raw contact id = 286. I can get a list of 7 messages... (see picture below, screenshot from my log)

B4X:
Sub Button2_Click
    Dim sm As SmsMessages
    Dim tList As List
    tList.Initialize
    tList = sm.GetByPersonId(286)
    Log(tList.Size)
    Dim m As Sms
    If tList.Size > 0 Then
        For i = 0 To tList.Size - 1
            m = tList.Get(i)
            If i = 0 Then
                Log(m.Address)
                Log(m.PersonId)
            End If
            Log(m.Body)
        Next
    End If
End Sub
 
Last edited:
Upvote 0
Top