How to return just the mobile number and name?

netchicken

Active Member
Licensed User
Longtime User
i have been writing a program (see in my manual) that pulls the name and phone number from the contacts list and compares it to incoming sms numbers. However in testing i found a bug in my code that leaves me stumped.

If you have multiple numbers, such as work, home and mobile, it only chooses home and not the mobile number. So contact.phonenumber selects home, not mobile.

Of course only the mobile number is important and home won't send sms messages. How can i filter for only mobile numbers?

Here is my working code

B4X:
Sub getcontacts
'create a Contacts to hold the contacts from your phone
Dim Contacts2 As Contacts2
'pass the contacts to a list to hold them. Note that each contact has about 6 or so fields, that at the moment you can't get to
listOfContacts = Contacts2.GetAll(True,False)

'loop through each of the contacts in your new list
For i = 0 To listOfContacts.Size - 1
'for each contact pass it to the Contact object. This object allows you to extract out each field held in field, so you can use Contact.phonenumber and Contact.DisplayName as well as many others.
    Dim Contact As Contact
    Contact = listOfContacts.Get(i)
   'Logging to check how it works
Log(Contact) 'will print the fields to the LogCat
  
'We don't want contacts who don't have a phone number or contacts with short number such as your phone provider. A 3 digit number will screw with the next part fo the code where we cut the beginning off.   
If Contact.phonenumber <>"" AND Contact.phonenumber.Length > 7 Then

'show the name and number from the constacts list in your listview and format it up to make it easy to read
lvphone.SingleLineLayout.Label.TextSize = 15
lvphone.SingleLineLayout.Label.TextColor = Colors.Black
lvphone.SingleLineLayout.ItemHeight = 40
lvphone.ScrollingBackgroundColor =Colors.Transparent
'data goes in here the name and number seperated by a :, this is what we use to get the name out later.
lvphone.AddSingleLine(Contact.DisplayName &": " & Contact.phonenumber)

   End If
Next

I have been tooling around with the following but have failed to be able to integrate it into my code. Contact.PHONE_MOBILE always gives back 2 and not the number. I suspect if I could filter by Contact.PHONE_MOBILE it might only show contact.phonenumber as the mobile number but its not working.
B4X:
Dim c As Contact
Dim phones As Map
phones = Contact.GetPhones
Dim p As String 'Holds the result
p = "N/A"
For i = 0 To phones.Size - 1
p = phones.GetKeyAt(i)
If phones.GetValueAt(i) = Contact.PHONE_MOBILE Then Exit
Next

attached is the full program
 

Attachments

  • smsinteceptor.zip
    17.8 KB · Views: 220
Last edited:

BarrySumpter

Active Member
Licensed User
Longtime User
I added these lines
B4X:
Log("")
    Log("listOfContacts: " & listOfContacts)
Log("")
No "Mobile" field flag.

I did notice that all my mobile numbers for australia only
were delimited with

PhoneNumber=04
and ,

or

PhoneNumber=(04
and ,

I'd use my extractBetween PhoneNumber= and , function
and remove all chars except numbers

Then test for size.

...
If you have multiple numbers, such as work, home and mobile, it only chooses home and not the mobile number. So contact.phonenumber selects home, not mobile.
...
Ah, right.
You could also see if you can access the contact file via sqlLite.
I know I have. Just to see what was in there.
But don't recall if anything was actually headed/field named "Mobile"

hth


EDIT ----

Try this:

You'll find the Phone numbers: list in the logs using this code.

NOTE: I found my "mobile number' designated with a suffix of =2
To me the =2 signified a field NAME and not an actual mobile number.
So I would suggest checking ALL phone numbers just in case.



i.e. Logs:
B4X:
...
Phone numbers: (MyMap) {#### ### ###=2, (##) ####-####=3, (##) ####-####=4}
...
Code copied from here:
http://www.b4x.com/forum/basic4android-updates-questions/10065-lib-phone-contacts.html#post78041


Tested under: b4a v1.92
B4X:
Sub getContactsBGS
    Dim Contacts2 As Contacts2
    Dim listOfContacts As List
    listOfContacts = Contacts2.GetAll(True,False)

    For i = 0 To listOfContacts.Size - 1
        Dim Contact As Contact
        Contact = listOfContacts.Get(i)
        Log(Contact) 'will print the fields to the LogCat
        Dim photo As Bitmap
        photo = Contact.GetPhoto
        Dim phones As Map
        phones = Contact.GetPhones
    
        If phones.Size > 0 Then 
        
        
            Log("Phone numbers: " & phones)

            Dim PhoneNum As String 'Holds the result
            PhoneNum = "N/A"
            For x = 0 To phones.Size - 1
                PhoneNum = phones.GetKeyAt(x)

                
                Log("PhoneNum(" & x & "): " & PhoneNum)

                ' remove any char other than numerics
                '    from myReceivedSMSFromPhoneNum to my_Filtered_ReceivedSMSFromPhoneNum
                '  AND from PhoneNum to my_Filtered_CONTACTPhoneNum
                
                'x = Replace(x,"(","")
                'x = Replace(x,")","")
                'x = Replace(x,"-","")
                  'x = Replace(x," ","")
 
'      - then do the comparison

                '

                ' i.e.
                '  If my_Filtered_ReceivedSMSFromPhoneNum = my_Filtered_CONTACTPhoneNum Then
                '        Return "FOUND"
                '  end if
 
                
                'NOT this cause there are too many variations in fomatting:
                'If phones.GetValueAt(x) = Contact.PHONE_MOBILE Then Exit

            Next
        End If
    
    Next


End Sub
hth
 
Last edited:
Upvote 0

netchicken

Active Member
Licensed User
Longtime User
Thanks Barry, Using your code I found that my code returns the last phone number in a list of numbers, regardless of their type.

So a list of All Phone numbers: (MyMap) {123456789=2, 142539987=3, 987654321=1} returns my list Test: 987654321 which is logical when you think about it the last one overwriting the others.

However in the code you posted For x = 0 To phones.Size - 1 the X only shows the place in the list of returned numbers, it could be in any order of phone types, mobile, home or work, 1, 2, 3 or 2, 1, 3 etc.

All Phone numbers: (MyMap) {123456789=2, 142539987=3, 987654321=1}
Just PhoneNum(0): 123456789
Just PhoneNum(1): 142539987
Just PhoneNum(2): 987654321

or
All Phone numbers: (MyMap) {12345699=2, 543 219 9=1, 98765499=3}
Just PhoneNum(0): 12345699
Just PhoneNum(1): 543 219 9
Just PhoneNum(2): 98765499

which makes returning just 2 fruitless.

Still lost on this one :)
 
Last edited:
Upvote 0

BarrySumpter

Active Member
Licensed User
Longtime User
.
...
NOTE: I found my "mobile number' designated with a suffix of =2
To me the =2 signified a field NAME and not an actual mobile number.
So I would suggest checking ALL phone numbers just in case.
...
I have a friend who doesn't have a home phone land line.
He only has his mobile number.
So I have his mobile number in my contacts for him under "Home Phone"

So really, any of the numbers could be a mobile number.
All or even none could be a mobile number.

So it doesn't really matter which one or if all are a mobile number.

I could even be all 8 number of a contact are mobile numbers.

But really we're only looking for the first matching contact phone number.

So you need to make sure you retrieve ALL phone numbers for all contact.
And compare ALL of them to the sms received from number your looking for.

So the actual SMS received from number your looking for of:
(xxxx) xx-xx-xx
needs to be filtered out leaving
xxxxxxxxxx


first phone number for this contact of:
(xx) xx xx x xxx
needs to be filtered out leaving
xxxxxxxxxx

then compare



and the next contacts number of
(xxxx) xxx xxx
needs to be filtered out leaving
xxxxxxxxxx

then compare


and the next for that contact of
xxxx xxxx
needs to be filtered out leaving
xxxxxxxx

then compare


etc


hth
 
Last edited:
Upvote 0

netchicken

Active Member
Licensed User
Longtime User
Indeed.

This returns only mobile numbers, however I need to tie that back into the names. I can't use contacts.phonenumber, as it might not contain the extracted PhoneNum from below. So i seem to be back at square 1.

B4X:
 For i = 0 To listOfContacts.Size - 1
        Dim Contact As Contact
        Contact = listOfContacts.Get(i)
      
      
        Log("New " & Contact) 'will print the fields to the LogCat
'     
        Dim phones As Map
        phones = Contact.GetPhones
    
        If phones.Size > 0 Then 
     
            Log("All Phone numbers: " & phones)

            Dim PhoneNum, Phonemob As String 'Holds the result
             For x = 0 To phones.Size - 1
              PhoneNum = phones.GetkeyAt(x)
           Phonemob = phones.GetvalueAt(x)
           
        If  Phonemob = 2 Then
               
                Log("PhoneNum " & PhoneNum & " " & Phonemob)

               End If
            Next
        End If
    
    Next
 
Last edited:
Upvote 0

netchicken

Active Member
Licensed User
Longtime User
I can do that.
You don't need to strip the formatting, I just cut the number down to the last 7 digits and compare them.

The problem is that under this code Contact = listOfContacts.Get(i)
it returns the data as these fields.

B4X:
 New DisplayName=Test, PhoneNumber=987654321, Starred=false, Id=159, Notes=, TimesContacted=0, LastTimeContacted=0, Name=Test

Now thats great except the person has 3 phone numbers (mobile, home, work) of which PhoneNumber=987654321 is only the last one in the list, and can be any of those three (see my previous post).

All Phone numbers: (MyMap) {123456789=2, 142539987=3, 987654321=1}
PhoneNum(0): 123456789
PhoneNum(1): 142539987
PhoneNum(2): 987654321

The individual Mobile, Home, work, numbers can only be extracted using the map. When that number (123456789) is extracted you can't go back and pull the name from the Contact as the only number to match it to is the wrong one, contact.phonenumber (PhoneNumber=987654321 )

Thats where I fall down :)
But more and stronger coffee may help ...

.
I have a friend who doesn't have a home phone land line.
He only has his mobile number.
So I have his mobile number in my contacts for him under "Home Phone"

So really, any of the numbers could be a mobile number.
All or even none could be a mobile number.

So it doesn't really matter which one or if all are a mobile number.

I could even be all 8 number of a contact are mobile numbers.

But really we're only looking for the first matching contact phone number.

So you need to make sure you retrieve ALL phone numbers.
And compare ALL of them to the sms received from number your looking for.

So the actual SMS received from number your looking for of:
(xxxx) xx-xx-xx
needs to be filtered out leaving
xxxxxxxxxx


first phone number for this contact of:
(xx) xx xx x xxx
needs to be filtered out leaving
xxxxxxxxxx

then compare

hth
 
Last edited:
Upvote 0

BarrySumpter

Active Member
Licensed User
Longtime User
...
and home won't send sms messages
...
Yes, they do.

Its called a "Missed Call Service".

I just rang my mobile.
Rejected the call.
An automated service picked up and asked me to record a 10 second message tha would be sent as text.
And it did.
My SMS receivded from number is my home phone number
and is a local number of xxxx xxxx
but fomated as an international number as +xxxxxxxxxxx.

So there is another format to test against.
LOL
 
Last edited:
Upvote 0

BarrySumpter

Active Member
Licensed User
Longtime User
I've update my coding example with some psudo code to give you more of an idea.

Be sure to filter all the non numerics from the phone numbers cause you can't guarantee the formatting of any of them.
 
Upvote 0

BarrySumpter

Active Member
Licensed User
Longtime User
...
This returns only mobile numbers
...
I believe this =2 is a FieldName of "Mobile" and could actually contain a NON-mobile number.

So, this returns only the contents of the field named "Mobile"
would be more accurate.

B4X:
DisplayName=Aaaa, PhoneNumber=1234 1234, Starred=false, Id=35, Notes=, TimesContacted=0, LastTimeContacted=0, Name=Aaaa
Phone numbers: (MyMap) {0407 846 646=3, 04 07 84 66 46=1, 1234 1234=2}
PhoneNum(0): 0407 846 646
PhoneNum(1): 04 07 84 66 46
PhoneNum(2): 1234 1234

hth
 
Last edited:
Upvote 0

netchicken

Active Member
Licensed User
Longtime User
Thats true, but we can't account for human error. I had a number in one contact that was a landline in my mobile field. I wonder if it might be best not to filter at all but just to search every number.

If you run the code on the attachment you can see that it does work, OK, just as long as the person doesn't have multiple phone numbers.

I believe this =2 is a FieldName of "Mobile" and could actually contain a NON-mobile number.

So, this returns only the contents of the field named "Mobile"
would be more accurate.
 
Upvote 0

BarrySumpter

Active Member
Licensed User
Longtime User
...
but we can't account for human error
...
We can and we do.
Well, as best we can, anyways.
Thats what IT is all about.

We do by checking all the numbers.

The only way we can check all the numbers properly,
is to remove all the special formatting characters
and leave only the numerics
from both the ReceivedSMSFrom number
AND from ALL the ContactsPhoneNumbers.
Then compare.

An exact match or perhaps a "contains" comparison of inStr().
 
Last edited:
Upvote 0

netchicken

Active Member
Licensed User
Longtime User
Update:
I think i solved it. As the mobile number is in the same loop as the the contact it derives from then Contact.DisplayName still works.

Log("PhoneNum " & PhoneNum & " " & Phonemob & " " & Contact.DisplayName)

Problem solved. it now returns every phone number with every persons name

B4X:
Sub getcontacts
    Dim Contacts2 As Contacts2
    Dim listOfContacts As List
    listOfContacts = Contacts2.GetAll(True,False)

    For i = 0 To listOfContacts.Size - 1
        Dim Contact As Contact
        Contact = listOfContacts.Get(i)
      
      
       ' Log("New " & Contact) 'will print the fields to the LogCat
'     
        Dim phones As Map
        phones = Contact.GetPhones
    
        If phones.Size > 0 Then 
             Dim PhoneNum, Phonemob As String 'Holds the result
             For x = 0 To phones.Size - 1
              PhoneNum = phones.GetkeyAt(x)
         '  Phonemob = phones.GetvalueAt(x)
           PhoneNum = PhoneNum.Replace(" ", "")
        If PhoneNum.Length > 7 Then
        
lvphone.SingleLineLayout.Label.TextSize = 15
lvphone.SingleLineLayout.Label.TextColor = Colors.Black
lvphone.SingleLineLayout.ItemHeight = 40
lvphone.ScrollingBackgroundColor =Colors.Transparent
lvphone.AddSingleLine(Contact.DisplayName &": " & PhoneNum)            
                     Log("PhoneNum " & PhoneNum & " "  & Contact.DisplayName)

               End If
            Next
        End If
    
    Next


End Sub
 
Last edited:
Upvote 0
Top