Android Question SMS Received Post KitKat

canalrun

Well-Known Member
Licensed User
Hello,
I've been searching the forums, but have not found what I think I need.

I'm probably in the minority, but I hardly ever look at my phone – except when I'm developing B4A :D.

I would like to develop a super-simple app for my own use that sends me an email when I receive a phone call or SMS on my Android phone.

The phone call detection I have working with PhoneStateChanged in a service, but from what I have read in the forums, it would probably be better to do this using intents.

I think I'm encountering the post-KitKat problem trying to use SMS_MessageReceived. I see that using Intents is a better solution and there are a new set of permissions post KitKat.

My situation is a little different in that all I want to know is that an SMS has been received – I don't need to alter or delete the SMS. My app will not be the default SMS app.

Is it possible to be notified if an SMS is received without being the default SMS app?

Is there a super-simple example on the forums of how to be notified, post-KitKat, if an SMS is received without being the default app, hopefully using Intents?

Thanks,
Barry.
 

canalrun

Well-Known Member
Licensed User
Thanks Star-Dust and Erel.

I still cannot get my phone to recognize when I receive an SMS. I'm either doing something wrong or it is likely possible that my cellular carrier does not use the normal Android SMS handlers. I use a free cellular provider, FreedomPop, that has its own SMS and phone call app. They use Wi-Fi if at all possible and they are known not to work nicely with other things, such as apps from Google.

My app is a tiny little test app that first shows a notification icon, then logs to a file if an SMS is received.

My manifest:
B4X:
AddManifestText(
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="14"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
SetApplicationAttribute(android:theme, "@android:style/Theme.Holo.Light")
'End of default text.
AddPermission(android.permission.READ_SMS)
AddPermission(android.permission.RECEIVE_SMS)
AddReceiverText(smssvc,
<intent-filter android:priority="999">
    <action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>)
My main activity:
B4X:
#Region  Project Attributes
  #ApplicationLabel: SMS Detect
  #VersionCode: 1
  #VersionName: 1.0
  'SupportedOrientations possible values: unspecified, landscape or portrait.
  #SupportedOrientations: portrait
  #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
  #FullScreen: False
  #IncludeTitle: True
#End Region

Sub Process_Globals
End Sub

Sub Globals
  Private pnMain As Panel
  Private bnStart, bnStop As Button
  Private lbStatus As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
  Activity.LoadLayout("Main")
  
  pnMain.SetLayout((100%x - pnMain.Width) / 2, (100%y - pnMain.Height) / 3, pnMain.Width, pnMain.Height)
End Sub

Sub Activity_Resume
  CallSubDelayed(Me, "UpdStatus")
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub Activity_KeyPress (KeyCode As Int) As Boolean
  Dim Answ As Int

  If (KeyCode = KeyCodes.KEYCODE_BACK) Then
    Answ = Msgbox2("Do you want to Quit?", "A T T E N T I O N", "Yes", "", "No", Null)
  
    If (Answ = DialogResponse.NEGATIVE) Then
      Return True
    End If
  End If

  Return False
End Sub

Sub bnStart_Click
  If (IsPaused("smssvc")) Then StartService("smssvc")

  CallSubDelayed(Me, "UpdStatus")
End Sub

Sub bnStop_Click
  If (IsPaused("smssvc") = False) Then StopService("smssvc")

  CallSubDelayed(Me, "UpdStatus")
End Sub

Sub UpdStatus
  If (IsPaused("smssvc")) Then
    lbStatus.Text = "Service Paused"
  
    bnStart.Enabled = True
    bnStart.TextColor = Colors.Black
  
    bnStop.Enabled = False
    bnStop.TextColor = Colors.RGB(200, 200, 200)
  
  Else
    lbStatus.Text = "Service Running"
  
    bnStop.Enabled = True
    bnStop.TextColor = Colors.Black
  
    bnStart.Enabled = False
    bnStart.TextColor = Colors.RGB(200, 200, 200)
  End If
End Sub
My service, called "smssvc":
B4X:
#Region  Service Attributes
  #StartAtBoot: False
#End Region

Sub Process_Globals
  Type Message (Address As String, Body As String)
End Sub

Sub Service_Create
End Sub

Sub Service_Start (StartingIntent As Intent)
  Utl.LogToFile("Got Intent")

  If (StartingIntent.Action = "android.provider.Telephony.SMS_RECEIVED") Then
    Dim messages() As Message
   
    messages = ParseSmsIntent(StartingIntent)

    Utl.LogToFile("SMS_RECEIVED")

    For i = 0 To messages.Length - 1
      Utl.LogToFile(Utl.Sprintf("  %s", Array As String(messages(i))))
    Next

  Else
    Utl.LogToFile(Utl.Sprintf("%s: Got Intent: %s", _
      Array As String(Utl.FormatDateTime("MM/dd hh:mm", DateTime.Now), StartingIntent.GetData)))
  
    Dim noti As Notification 'shows in the notification window

    noti.Initialize

    noti.Icon = "icon"
    'noti.Notify(1)
    noti.Sound = False
    noti.Vibrate = False
    noti.Light = False

    noti.SetInfo("SMS Detect", "Running", Main)

    Service.StartForeground(1, noti)
  End If
End Sub

Sub Service_Destroy
  Service.StopForeground(1)
End Sub

'Parses an SMS intent and returns an array of messages
Sub ParseSmsIntent (In As Intent) As Message()
   Dim messages() As Message
 
   If (In.HasExtra("pdus") = False) Then Return messages
 
   Dim pdus() As Object
   Dim r As Reflector
 
   pdus = In.GetExtra("pdus")
 
   If (pdus.Length > 0) Then
      Dim messages(pdus.Length) As Message
    
      For i = 0 To pdus.Length - 1
         r.Target = r.RunStaticMethod("android.telephony.SmsMessage", "createFromPdu", _
            Array As Object(pdus(i)), Array As String("[B"))
          
         messages(i).Body = r.RunMethod("getMessageBody")
         messages(i).Address = r.RunMethod("getOriginatingAddress")
      Next
   End If
 
   Return (messages)
End Sub
I've also appended a zip file export with my code. There are several handy utilities, but I have to warn they were written long before I had any understanding of how type casts and conversions worked in basic or B4A – they have always worked, but user beware :D.

My phone runs Android 5.01.

I'm also still using B4A 4.30, simply because I'm too lazy to install the updated versions. It may be possible that this has something to do with the SMS detection not working.

Does anyone spot any obvious errors?

Thanks,
Barry.
 

Attachments

Last edited:

Star-Dust

Expert
Licensed User
Try this:
 

Attachments

canalrun

Well-Known Member
Licensed User
Thanks.

But, unfortunately nothing.

I can see the notification icon show up when I run your app (I'm in Debug mode), but I send an SMS message from a different phone and your debug message does not show, although the SMS message is received by the FreedomPop SMS app.

Does this report SMSs received on your phone? What version of Android is on your phone?

I will see if I can get hold of a phone that does not use FreedomPop. I have a feeling that they may use nonstandard stuff and this might be the problem.

Barry.
 

Star-Dust

Expert
Licensed User
Thanks.

But, unfortunately nothing.

I can see the notification icon show up when I run your app (I'm in Debug mode), but I send an SMS message from a different phone and your debug message does not show, although the SMS message is received by the FreedomPop SMS app.

Does this report SMSs received on your phone? What version of Android is on your phone?

I will see if I can get hold of a phone that does not use FreedomPop. I have a feeling that they may use nonstandard stuff and this might be the problem.

Barry.
It's a piece of software I've made that intercepts messages and automatically responds to messages by sender. I've tried it on different versions (2.1, 4.0, 4.2, 5.0 ,6.0) of Android and different devices (Samsung, Asus, Wiko, Mediacom, Huawey, Alp), because I've published it on Goggle Play and so before I do many tests.

If it does not work I will not know how to help you, will not it be your device? What do you do about it?
 

Star-Dust

Expert
Licensed User
Last attempt, no more ideas.

With this code a timer with regular expiration checks whether there are new messages. Check it by reading the date of the last read message.
This method is not very reliable because sometimes reversed SMS arrives, at least here in italy (But here you know everything works late).

If the last message arrives has a higher value than the last message being viewed then it means there are other messages coming from and they search for them from the date of the last message being reviewed.

You can also control the ID of the last received SMS. You can change it as you like

I hope you solve it ... otherwise it changes device

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim Tim1 As Timer
    Dim LastSMS As Long = 0
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    Tim1.Initialize("Tim1",1000)
    Tim1.Enabled=True
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub Tim1_Tick
    Dim SmsMessages1 As SmsMessages
    Dim Sms1 As Sms
    Dim L As Long

    L=ReadLastSMS
    If LastSMS<>l Then
        Dim ListSMS As List = SmsMessages1.GetBetweenDates(LastSMS,DateTime.Now)
        ' View new message
        For i=0 To ListSMS.Size-1       
            Sms1=ListSMS.Get(i)
            LogColor("New sms",Colors.Red)
            Log(Sms1.Address)
            Log(Sms1.Body)
        Next
        LastSMS=l
    End If
End Sub

Sub ReadLastSMS As Long
    Dim SmsMessages1 As SmsMessages
    Dim Sms1 As Sms
    Dim L As Long

    L=0
    If SmsMessages1.getByType(SmsMessages1.TYPE_INBOX).Size>0 Then
        Sms1 = SmsMessages1.getByType(SmsMessages1.TYPE_INBOX).Get(0)
        L=Sms1.Date
    End If
    Return L
End Sub
 
Top