KillCall, SendCall, SendSMS aren't mine, the rest are.
Some of the contacts API from the Phone library didn't work, so I was forced to replace it. Now my first versions were slow (+1 minute for some) so I had to do a bunch of clever caching to speed it up. As such, I am sharing that.
I may have used API from other modules of mine, so tell me if I missed anything
Some of the contacts API from the Phone library didn't work, so I was forced to replace it. Now my first versions were slow (+1 minute for some) so I had to do a bunch of clever caching to speed it up. As such, I am sharing that.
I may have used API from other modules of mine, so tell me if I missed anything
B4X:
Sub Process_Globals
Dim YourName As String ,UnreadThreads As Int , PhoneNumbers As Map
End Sub
Sub GetPhoneVolume As Int
Dim p As Phone
Select Case p.GetRingerMode
Case p.RINGER_NORMAL: Return p.GetVolume( p.VOLUME_RING )
Case p.RINGER_SILENT: Return 0
Case p.RINGER_VIBRATE: Return -1
End Select
End Sub
Sub GetMonth(Month As Int, LongForm As Boolean) As String
Dim text() As String = Array As String("JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER")
If LongForm Then
Return text(Month)
Else
Return Left(text(Month),3)
End If
End Sub
Sub GetDuration(Seconds As Int) As String
Dim tempstr As StringBuilder ,temp As Long
tempstr.Initialize
Seconds = DurTest(Seconds, tempstr, 3600, "HRS")
Seconds = DurTest(Seconds, tempstr, 60, "MIN")
Seconds = DurTest(Seconds, tempstr, 1, "SEC")
If tempstr.Length=0 Then Return "0 SEC"
Return tempstr.ToString
End Sub
Sub DurTest(TimeDate As Long, tempstr As StringBuilder, Ticks As Int, Text As String) As Int
Dim temp As Int
If TimeDate>= Ticks Then
temp = Floor(TimeDate/Ticks)
Log(temp)
TimeDate = TimeDate Mod Ticks
If temp = 1 Then Text = Text.Replace("S","")
tempstr.Append(IIF(tempstr.Length=0, "", ", ") & temp & " " & Text)
End If
Return TimeDate
End Sub
Sub HowLongAgo(TimeDate As Long) As String
Dim Diff As Long,Text As String
Diff = DateTime.Now - TimeDate
If Diff < DateTime.TicksPerMinute Then
Return "<1 MIN AGO"
Else If Diff < DateTime.TicksPerHour Then
Diff = Floor(Diff / DateTime.TicksPerMinute)
Text = "MIN"
Else If Diff < DateTime.TicksPerDay Then
Diff = Floor(Diff / DateTime.TicksPerHour)
Text= "HRS"
Else If Diff< DateTime.TicksPerDay * 7 Then
Diff = Floor(Diff / DateTime.TicksPerDay)
Text = "DAYS"
Else If Diff< (DateTime.TicksPerDay * 30) Then
Diff = Floor(Diff / (DateTime.TicksPerDay*7))
Text = "WKS"
Else If Diff < (DateTime.TicksPerDay * 365) Then
Diff = Floor(Diff / (DateTime.TicksPerDay*30))
Text= "MTHS"
Else
Diff = Floor(Diff / (DateTime.TicksPerDay*365))
Text = "YRS"
End If
If Diff= 1 Then Text = Text.Replace("S", "")
Return Diff & " " & Text & " AGO"
End Sub
'Form: 0=Full name, 1=Initials + Last name, 2= Last name
Sub GetUserName(Form As Int) As String
Dim pid As PhoneId, tempContact As Contact , text() As String, tempstr As StringBuilder ,temp As Int
If YourName.Length=0 Then
Try
'Log("YOUR PHONE NUMBER: " & pid.GetLine1Number)
'tempContact=EnumContacts(pid.GetLine1Number,True).Get(0)
'tempContact=GetContactByPhoneNumber(pid.GetLine1Number)
'If tempContact <> Null Then
'Log("FULL: " & tempContact)
'YourName=tempContact.DisplayName
tempContact=GetContactByPhoneNumber(pid.GetLine1Number)
'Log("FAST: " & tempContact)
YourName=tempContact.DisplayName
Catch
Return pid.GetLine1Number
End Try
End If
If Form=0 Then
Return YourName
Else
text = Regex.Split(" ", YourName)
If Form = 2 Then
Return text(text.Length-1)
Else
tempstr.Initialize
For temp = 0 To text.Length-2
tempstr.Append( Left(text(temp),1).ToUpperCase & ". ")
Next
tempstr.Append( Left(text(text.Length-1), 1).ToUpperCase & Right(text(text.Length-1), text(text.Length-1).Length -1).ToLowerCase )
Return tempstr.ToString
End If
End If
End Sub
Sub GetContactByPhoneNumber(PhoneNumber As String) As Contact
Dim ContactList As List , tempContact As Contact,tempContact2 As Contact, tempstr As String , NeedsInit As Boolean ,temp As Int, temp2 As Int,tempMap As Map ,CON As Contacts2
If Not(PhoneNumbers.IsInitialized) Then
NeedsInit =True
PhoneNumbers.Initialize
Else If PhoneNumbers.Size=0 Then
NeedsInit =True
End If
If NeedsInit Then
YourName=""
ContactList= EnumContacts("",True)
For temp = 0 To ContactList.Size-1
tempContact = ContactList.Get(temp)
If Not(tempContact.DisplayName.EqualsIgnoreCase("MiPhone")) Then
tempMap=tempContact.GetPhones
For temp2 = 0 To tempMap.Size-1
tempstr=FilterPhoneNumber(tempMap.GetKeyAt(temp2))
If PhoneNumbers.ContainsKey(tempstr) Then
If Not( tempContact.PhoneNumber.EqualsIgnoreCase(tempContact.DisplayName)) Then
PhoneNumbers.Put(tempstr, tempContact.Id)
'Log("DUPE " & tempContact)
End If
Else
PhoneNumbers.Put(tempstr, tempContact.Id)
End If
Next
End If
Next
End If
tempstr=FilterPhoneNumber(PhoneNumber)
temp=PhoneNumbers.GetDefault(tempstr,-1)
If temp>-1 Then tempContact2 = CON.GetById(temp,True,True)
Return tempContact2
'ContactList = EnumContacts(tempstr,True)
'If ContactList.Size>0 Then tempContact = ContactList.Get(0)
'Return tempContact
End Sub
Sub FilterPhoneNumber(Number As String) As String
If Left(Number,1) = "+" Then Number= Right(Number, Number.Length-2)
Return RemoveAllExceptNumbers(Number)
End Sub
Sub KillCall'AddPermission("android.permission.CALL_PHONE")
Dim r As Reflector
r.Target = r.GetContext
Dim TelephonyManager, TelephonyInterface As Object
TelephonyManager = r.RunMethod2("getSystemService", "phone", "java.lang.String")
r.Target = TelephonyManager
TelephonyInterface = r.RunMethod("getITelephony")
r.Target = TelephonyInterface
r.RunMethod("endCall")
End Sub
Sub SendCall(PhoneNumber As String)
Dim p As PhoneCalls
StartActivity(p.Call(PhoneNumber))
End Sub
Sub SendTextMessage(PhoneNumber As String, Message As String)As Boolean
Dim SmsManager As PhoneSms ,r As Reflector, parts As Object
Try
If Message.Length <= 160 Then
SmsManager.Send(PhoneNumber, Message)
Else
r.Target = r.RunStaticMethod("android.telephony.SmsManager", "getDefault", Null, Null)
parts = r.RunMethod2("divideMessage", Message, "java.lang.String")
r.RunMethod4("sendMultipartTextMessage", Array As Object(PhoneNumber, Null, parts, Null, Null), Array As String("java.lang.String", "java.lang.String", "java.util.ArrayList", "java.util.ArrayList", "java.util.ArrayList"))
End If
Return True
Catch
Return False
End Try
End Sub
Sub FindContactID(ID As Int, ContactList As List) As Int
Dim temp As Int, tempContact As Contact
For temp = 0 To ContactList.Size-1
tempContact= ContactList.Get(temp)
If tempContact.ID=ID Then Return temp
Next
Return -1
End Sub
Sub GetContactByID(ID As Int) As Contact
Dim CON As Contacts2
Return CON.GetById(ID,True,True)
End Sub
'Name = * = favorites, [text]* = name must start with [text], # = starts with a number, [number] = find by phone number, [number]+[any other symbol] = find by id number
Sub EnumContacts(Name As String, HasNames As Boolean) As List
Dim CON As Contacts2 ,tempContact As Contact, Names As List, Special As Int,DoRemove As Boolean 'returns a list of type Contact
Dim temp As Int, temp2 As Int, tempContact As Contact , tempMap As Map,tempstr As String
If Name.Length =0 OR Name = "*" OR Name = "#" OR IsNumber(Name) Then
Names = CON.GetAll(True,False)
Select Case Name
Case "*": Special = 1'get favorites
Case "#": Special = 3'get names starting with number
Case Else:If IsNumber(Name) Then Special = 4'get by phone number
End Select
Else If IsNumber(RemoveAllExceptNumbers(Name)) Then'get by id number
Names.Initialize
tempContact = CON.GetById(Name,True,True)
If tempContact<> Null Then Names.Add(tempContact)
Return Names
Else If Name.Contains("@") AND Name.Contains(".") Then'get by email address
Names = CON.FindByMail(Name,False,True,True)
Else'get by name
If Right(Name,1)= "*" Then'get names starting with text
Special=2
Name = Left(Name, Name.Length-1).ToUpperCase
End If
Names = CON.FindByName(Name,False, True,True)
End If
If Names<>Null AND Names.IsInitialized Then
If Special>0 OR HasNames Then
For temp = Names.Size-1 To 0 Step -1
tempContact= Names.Get(temp)
DoRemove=False
If HasNames Then
If tempContact.DisplayName.Contains("@") Then
DoRemove =True
Else If tempContact.DisplayName.EqualsIgnoreCase("DISQUS") Then
DoRemove =True
Else If tempContact.DisplayName.Contains(", (Google+)") Then
DoRemove =True
Else If tempContact.DisplayName.Trim.Length=0 Then
DoRemove =True
End If
End If
If Not(DoRemove) Then
Select Case Special
Case 1'favorites only
If Not(tempContact.Starred) Then DoRemove=True
Case 2'starts with name text
If Not(tempContact.Name.ToUpperCase.StartsWith(Name)) Then DoRemove=True
Case 3'starts with a number
If isnumber(left(tempContact.Name,1)) Then DoRemove=True
Case 4'search by phone number
DoRemove=True
tempMap=tempContact.GetPhones
For temp2 = 0 To tempMap.Size-1
tempstr=RemoveAllExceptNumbers(tempMap.GetKeyAt(temp2))
If tempstr = Right(Name, tempstr.Length) Then
DoRemove=False
temp2=tempMap.Size
End If
Next
End Select
End If
If DoRemove Then Names.RemoveAt(temp)
Next
End If
'debug
' For temp = 0 To Names.Size-1
' tempContact= Names.Get(temp)
' tempMap= tempContact.GetEmails
'
' 'If tempContact.PhoneNumber.Length>0 Then Log(tempContact.DisplayName & " " & tempContact.PhoneNumber )
' tempMap=tempContact.GetPhones
' If tempMap.Size>0 Then
' 'Log(tempContact)
' Log(tempContact.DisplayName & " " & tempMap)
'
' EnumCallLogs(20,tempMap)
' EnumSMSmessages(tempContact.Id)
' End If
' Next
End If
If Names=Null Then
Names.Initialize
'Else
'Names.SortType("DisplayName", True)
End If
Return Names
End Sub
'Zero = all
Sub EnumCallLogsByID(Quantity As Int, PersonID As Int) As List
Dim Calls As List, CallLog As CallLog
Try
Calls = CallLog.GetById(PersonID)
Catch
End Try
If Not(Calls.IsInitialized) Then Calls.Initialize
Return Calls
End Sub
'Zero = all
Sub EnumCallLogs(Quantity As Int, Phones As Map) As List
Dim Calls As List, CallLog As CallLog,temp As Int, temp2 As Int,Found As Boolean ,tempstr As String
Calls = CallLog.GetAll(Quantity)
If Phones.IsInitialized Then'filter by contact info
For temp = Calls.Size - 1 To 0 Step -1
Dim c As CallItem
Found=False
c = Calls.Get(temp)
tempstr=RemoveAllExceptNumbers(c.Number)
For temp2 = 0 To Phones.Size-1
If RemoveAllExceptNumbers(Phones.GetKeyAt(temp2)) = tempstr Then
Found=True
temp2=Phones.Size
End If
Next
If Not(Found) Then Calls.RemoveAt(temp)
Next
End If
'debug
' For temp = 0 To Calls.Size - 1
' Dim c As CallItem, callType, name As String
' c = Calls.Get(temp)
' Select c.callType
' Case c.TYPE_INCOMING: callType = "Incoming"
' Case c.TYPE_MISSED: callType = "Missed"
' Case c.TYPE_OUTGOING: callType = "Outgoing"
' End Select
' name = c.CachedName
' If name.Length = 0 Then name = "N/A"
' Log("Number=" & c.Number & ", Name=" & name & ", Type=" & callType & ", Date=" & DateTime.Date(c.Date))
' Next
If Not(Calls.IsInitialized) Then Calls.Initialize
Return Calls
End Sub
'-1 = all unread
Sub EnumSMSmessages(PersonID As Int) As List
Dim SmsMessages1 As SmsMessages, List1 As List
If PersonID=-1 Then
List1 = SmsMessages1.GetUnreadMessages
Else
List1 = SmsMessages1.GetByPersonId(PersonID)
If List1.Size=0 Then
Dim tempContact As Contact ,CON As Contacts2, tempMap As Map, temp As Int, temp2 As Int ,theSms As Sms, Include As Boolean ,tempstr As String
List1 = SmsMessages1.GetAll
tempMap.Initialize
'tempContact = CON.GetById(PersonID,False,False)
'tempMap = tempContact.GetPhones
For temp = List1.Size - 1 To 0 Step -1
theSms = List1.Get(temp)
tempstr=FilterPhoneNumber(theSms.Address )
If tempMap.ContainsKey(tempstr) Then
Include=tempMap.Get(tempstr)
Else
Include=True
tempContact=GetContactByPhoneNumber(theSms.Address)
If tempContact=Null Then
Include=False
Else If Not(tempContact.Id = PersonID) Then
Include=False
End If
tempMap.Put(tempstr,Include)
End If
'tempstr=FilterPhoneNumber(theSms.Address)
'For temp2 = 0 To tempMap.Size-1
' If tempstr = FilterPhoneNumber(tempMap.GetKeyAt(temp2)) Then
' Include=True
' temp2=tempMap.Size
' End If
'Next
If Not(Include) Then List1.RemoveAt(temp)
Next
End If
End If
List1.SortType("Id",True)
'debug
' Log(List1.Size & " messages found for person " & PersonID)
' For i = 0 To List1.Size - 1
' theSms = List1.Get(i)'Type: 1=to you, 2=from you
' Log(theSms)
' Next
'
Return List1
End Sub
Sub GetContactByThreadID(ThreadID As Int) As Contact
Dim SmsMessages1 As SmsMessages, List1 As List,tempContact As Contact,theSms As Sms
List1 = SmsMessages1.GetByThreadId(ThreadID)
If List1.Size>0 Then
theSms= List1.Get(0)
Return GetContactByPhoneNumber(theSms.Address)
End If
Return tempContact
End Sub
Sub EnumSMSmessagesByThread(ThreadID As Int) As List
Dim SmsMessages1 As SmsMessages, List1 As List
If ThreadID=-1 Then'enum threads
Dim temp As Int ,theSms As Sms, List2 As List ,tempMap As Map,temp2 As Int
List1.Initialize
tempMap.Initialize
Log("Getting SMS messages")
List2 = SmsMessages1.GetAll
For temp = List2.Size - 1 To 0 Step -1
theSms = List2.Get(temp)
If List1.IndexOf(theSms.ThreadId)=-1 Then List1.Add(theSms.ThreadId)
If Not(theSms.Read) Then tempMap.Put(theSms.ThreadId, False)
Next
List1.Sort(True)
Log("Sorting by unread")
'put unread threads at the top
For temp = List1.Size-1 To 1 Step -1
temp2= List1.Get(temp)
If Not(tempMap.GetDefault(temp2, True)) Then
List1.RemoveAt(temp)
List1.InsertAt(0, temp2)
temp=temp+1
End If
Next
UnreadThreads = tempMap.Size
Else
List1 = SmsMessages1.GetByThreadId(ThreadID)
End If
Return List1
End Sub
Sub AddressOfThread(ThreadID As Int) As String
Dim SmsMessages1 As SmsMessages, List1 As List,theSms As Sms
List1 = SmsMessages1.GetByThreadId(ThreadID)
If List1.Size>0 Then
theSms= List1.Get(0)
Return FilterPhoneNumber(theSms.Address)
End If
Return ""
End Sub
Sub RemoveAllExceptNumbers(Text As String) As String
Dim tempstr As StringBuilder ,temp As Int ,Chars As String
tempstr.Initialize
For temp = 0 To Text.Length-1
Chars=Mid(Text,temp,1)
If IsNumber(Chars) Then tempstr.Append(Chars)
Next
Return tempstr.ToString
End Sub
Sub Left(Text As String, Length As Long)As String
If Length>Text.Length Then Length=Text.Length
Return Text.SubString2(0, Length)
End Sub
Sub Right(Text As String, Length As Long) As String
If Length>Text.Length Then Length=Text.Length
Return Text.SubString(Text.Length-Length)
End Sub
Last edited: