Android Tutorial Intent Filters - Intercepting SMS messages in the background

Status
Not open for further replies.

guidoarfini

Member
Licensed User
Longtime User
I looked at the phone library:sign0085:, but I do not understand how to catch the action "send message", since I will not get this from the log, but I would like that every time they send is stored in a db, even if the user deletes the sms ...
 

lemonisdead

Well-Known Member
Licensed User
Longtime User
Hello,

May I ask you more on how to use the intents and especially how you found the correct intent provider from the Android's documentation, please ? Starting from your example, I searched for "SMS_RECEIVED" and the result points to http://developer.android.com/reference/android/telephony/package-summary.html so I understand the root of the intent "android.provider.telephony" (even if the class listed on the android's site is "android.telephony". But from that page I don't find any link to the "SMS_RECEIVED" last part of your intent. So I am a bit lost...

Thanks a lot
 

lemonisdead

Well-Known Member
Licensed User
Longtime User
Hello NJDude,

Thanks for the link. I read and tried to understand but perhaps because English is not my native language, I still do not understand where (from the Android's site) to find the intent class to put into the manifest file. Especially about Static receivers.

Taking again and again Erel's tutorial, I never can find the correct action from the API #14 : android.provider.Telephony.SMS_RECEIVED
It is probably written but I don't find it. So, if I scout the API, I find the package name 'android.telephony' but never 'SMS_RECEIVED'
 

lemonisdead

Well-Known Member
Licensed User
Longtime User
Hello Erel,

In fact, I try to understand the tutorial and especially where to find the information about the intent to use in the manifest. Refering to Android's Reference I never find the "provider.telephony" nor "SMS_RECEIVED". But they exist and your example proves it

Let's take another example, perhaps it could be simpler : launch an app when the phone is ringing (not to have a service always running).
I search the reference and I get "android.telephony.PhoneStateListener" pointing to "CALL_STATE_RINGING". On this last page, the class has become "android.telephony.TelephonyManager" with a public constructor "PhoneStateListener".

They say:

So, I guess I should put this in the manifest (with S1 the name of the service in the activity to start) ?
B4X:
AddPermission(android.permission.READ_PHONE_STATE)
AddReceiverText(s1,
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>)

and detect the RINGING state inside the service launched or by adding the EXTRA_STATE state filter with the CALL_STATE_RINGING
 
Last edited:

Rolando Bertone

New Member
Licensed User
Longtime User
Hello to all.
I am a new user and i do not understand how to retrieve the sms smessage trapped by the S1 service module.
Can someone post an example of how to place the message in an edittext and in a string variable in my main module?

Thank you.

Rolando
 

LucaMs

Expert
Licensed User
Longtime User
I have read (rather quickly) this tutorial and the description of this same subject in the Phone Library v1.75.

What I want to achieve is:
give the opportunity to the user to enable the reception of a SMS in his (my) application at his discretion, or when he is waiting for a sms suitable for the app.

That is, I do not want a service that is constantly listening (also consume the battery, right? But not only for this reason).

Which method do you recommend?

Thank you in advance
 

gawie007

Member
Licensed User
Longtime User
You will not be able to abort the broadcast with the static intent filter.
Hi Erel,
I ask in hope!: Has anyone found a way around this as yet (reflection library maybe)?

I am specifically using intents so that I am almost guaranteed to receive messages from instruments in the field.
These send their information at midnight - the end of a 24 hour day.
In order to not wake any users, I would like to consume the SMS.
I then automatically send out SMS's to various key personnel at say around 08H00 with the data received at midnight.

If not then I will have to find a way of muting the message when it is received - if that is possible.
I know SMS's, when broadcast, don't wait around too long for code to execute, so may already be producing sound while the app is trying to mute it.
 

gawie007

Member
Licensed User
Longtime User
You will not be able to abort the broadcast with the static intent filter.
Hi Erel,
I ask in hope!: Has anyone found a way around this as yet (reflection library maybe)?

I am specifically using intents so that I am almost guaranteed to receive messages from instruments in the field.
These send their information at midnight - the end of a 24 hour day.
In order to not wake any users, I would like to consume the SMS.
I then automatically send out SMS's to various key personnel at say around 08H00 with the data received at midnight.

If not then I will have to find a way of muting the message when it is received - if that is possible.
I know SMS's, when broadcast, don't wait around too long for code to execute, so may already be producing sound while the app is trying to mute it.
 

gawie007

Member
Licensed User
Longtime User
Reflection will not help. You can use a dynamic receiver and use Service.StartForeground to keep it running all the time.
Thank you Erel, but if it is dynamic and it is shut down I could miss the message. With intents, my service will be restarted if necessary every time a SMS comes in.

I found this: http://stackoverflow.com/questions/5380192/sms-receive-with-no-notification
B4X:
<receiver android:name="mypackage.SMSReceiver">
  <intent-filter>
    <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
  </intent-filter>
</receiver>

<uses-permission android:name="android.permission.RECEIVE_SMS" />

B4X:
public class SMSReceiver extends BroadcastReceiver
{
  @Override
  public void onReceive(Context context, Intent intent)
  {
    Bundle extras = intent.getExtras();

    Object[] pdus = (Object[])extras.get("pdus");
    for (Object pdu: pdus)
    {
      SmsMessage msg = SmsMessage.createFromPdu((byte[])pdu);

      String origin = msg.getOriginatingAddress();
      String body = msg.getMessageBody();

      // Parse the SMS body
      if (isMySpecialSMS)
      {
        // Stop it being passed to the main Messaging inbox
        abortBroadcast();
      }
    }
  }
}

This had the following comments:
While this does answer the question correctly, you should not do this. Other apps might want or need to receive the SMS_RECEIVED broadcast. Aborting it will disrupt 3rd party apps from running properly. This is a bad way to program.

The class (service?) above is started by an intent.
I know that it is my module sending me the information (Tel No. and the way the message is composed), so no other app would need the message.
I will only be aborting it if is 15 minutes either side of midnight. Any other time I want to be notified - alarms etc.
Am I missing something?

I have come up with something that works; a second Service that stops ringing and vibrating (23:50 to 00:10):
B4X:
#Region  Service Attributes
    #StartAtBoot: true
#End Region

Sub Process_Globals

    Dim muteTimer As Timer
    Dim busyCreatingService As Boolean
    Dim ringMode As Int
 
End Sub
Sub Service_Create

    busyCreatingService = True

End Sub

Sub Service_Start (StartingIntent As Intent)

    Dim HH As Int = 11
    Dim MM As Int = 50
 
    StartServiceAt(Me, NextTimeInstance(HH, MM) ,True)
 
    If busyCreatingService = False Then        'Running, NOT initialising
        Log("Muting messages")
        Dim p As Phone
        ringMode = p.GetRingerMode
        p.SetRingerMode(p.RINGER_SILENT)
        Log("Set ringermode from " & ringMode & "to " & p.GetRingerMode)
        muteTimer.Initialize("muteTimer", 1000*60*2) 'Test 2 min, 20 min when running
        muteTimer.Enabled = True
    End If
    busyCreatingService = False
 
End Sub

Sub muteTimer_Tick

    Log("UNmuting messages")
    Dim p As Phone
    muteTimer.Enabled = False
    p.SetRingerMode(ringMode)
    Log("Set ringermode back to: " & p.GetRingerMode)

End Sub

Sub NextTimeInstance (Hours As Int, Minutes As Int) As Long
  'Code courtesy of Erel:
      Dim today As Long = DateTime.Now
      today = DateUtils.SetDateAndTime(DateTime.GetYear(today), DateTime.GetMonth(today), _
        DateTime.GetDayOfMonth(today), Hours, Minutes, 0)
      If today < DateTime.Now Then
        Dim p As Period
        p.Days = 1
        Dim tomorrow As Long = DateUtils.AddPeriod(today, p)
        Return tomorrow
      Else
        Return today
      End If

End Sub

Sub Service_Destroy

End Sub
 
Last edited:

gawie007

Member
Licensed User
Longtime User
This is why I wrote that you should call Service.Startforeground. The process will not be killed.
Hi Erel, please excuse my ignorance ... I don't mean to be a pain in the butt!

From the Service Module tutorial:
Paused processes are the first to be killed when needed. If there is still not enough memory, background processes will be killed.
Foreground processes will usually not be killed.
if this read "Foreground processes will not be killed"


Would this foreground state not be lost once another Activity is opened(come to the foreground) since they are on the same thread?

Understanding this will be extremely beneficial to me since I need to know that I will not miss incoming data.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…