0

I would like to have the information when a user receives/sends an SMS. I have created a SmsWatcher class for this purpose.

using AeroMobile.Utility.Helper;
using Android.App;
using Android.Content;
using Android.Provider;

[BroadcastReceiver]
[IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED", "android.intent.action.SENDTO", "android.provider.Telephony.SMS_DELIVER" }, Priority = (int)IntentFilterPriority.HighPriority)]
public class SmsWatcher : BroadcastReceiver
{

public override async void OnReceive(Context context, Intent intent)
{
    if (intent.Action != null)
    {
        if (intent.Action.Equals(Telephony.Sms.Intents.SmsReceivedAction))
        {
            var msgs = Telephony.Sms.Intents.GetMessagesFromIntent(intent);
            foreach (var msg in msgs)
            {
                //incoming message
            }
        }
        if (intent.Action.Equals(Telephony.Sms.Intents.SmsDeliverAction))
        {
            var msgs = Telephony.Sms.Intents.GetMessagesFromIntent(intent);
            foreach (var msg in msgs)
            {
                //outgoing message
            }
        }
    }
}

}

and I register this broadcast service in the MainActivity like below:

    //starting SMS watcher service
    var smsWatcherIntent = new Intent(ApplicationContext, typeof(SmsWatcher));
    SendBroadcast(smsWatcherIntent);

Above code perfectly works for the incoming messages but not for outgoing messages. Can you please help me to get information when a user sends SMS like the information I am getting for incoming messages?

Mohamed Thaufeeq
  • 1,667
  • 1
  • 13
  • 34
  • Don't you need to use android.intent.action.SENDTO ? – Jon Apr 23 '19 at 13:49
  • @Jon, thanks and yes, I used that too. Still, it is not working. The question was updated too. – Mohamed Thaufeeq Apr 23 '19 at 13:57
  • SmsDeliverAction is not the right Intent. (taken from the documentation): SMS_DELIVER_ACTION Broadcast Action: A new text-based SMS message has been received by the device. – Jon Apr 23 '19 at 13:59
  • @Jon I was having a line break on the if condition to look at the Intent.Action. An OnReceive method is not even triggered when I send an SMS. :-( – Mohamed Thaufeeq Apr 23 '19 at 14:02
  • I don't think there is a way to intercept outgoing SMS messages, but I could be wrong. You could try this other Stack post https://stackoverflow.com/questions/848728/how-can-i-read-sms-messages-from-the-device-programmatically-in-android – Jon Apr 23 '19 at 14:02
  • You cannot use SMS_DELIVER_ACTION, it doesn't do what you think it does – Jon Apr 23 '19 at 14:03
  • Yes. Hence I am looking for a solution. – Mohamed Thaufeeq Apr 23 '19 at 14:04
  • Look above, I posted another stack question where the user wants to read the SMS messages on the device. You'll need to develop an algorithm to periodically check these and use a timestamp or ID to filter the new ones. – Jon Apr 23 '19 at 14:05
  • I can see the answer focusing mostly on the incoming messages. I could do that through SmsReceivedAction Intent. Anyway, I will follow the idea and create periodic service for that. Thanks for your help, anyway! – Mohamed Thaufeeq Apr 23 '19 at 14:54

1 Answers1

1

Per the inspiration from this answer

It seems it is NOT that easy to read outgoing messages from the BroadcastReceiver. Hence, the best way to read SMS is from the Android Database through Cursor.

Below is the code snippet for Xamarin.Android:

    private async Task CheckAndUpdateSms(Context context)
    {
        string lastReadTimeMilliseconds = Application.Current.Properties["LastSmsReadMilliseconds"].ToString();
        ICursor cursor = context.ContentResolver.Query(Telephony.Sms.ContentUri, null, "date > ?", new string[] { lastReadTimeMilliseconds }, null);

        if (cursor != null)
        {
            int totalSMS = cursor.Count;
            if (cursor.MoveToFirst())
            {
                double maxReceivedTimeMilliseconds = 0;

                for (int j = 0; j < totalSMS; j++)
                {
                    double smsReceivedTimeMilliseconds = cursor.GetString(cursor.GetColumnIndexOrThrow(Telephony.TextBasedSmsColumns.Date)).ToProperDouble();
                    string smsReceivedNumber = cursor.GetString(cursor.GetColumnIndexOrThrow(Telephony.TextBasedSmsColumns.Address));
                    int smsType = cursor.GetString(cursor.GetColumnIndexOrThrow(Telephony.TextBasedSmsColumns.Type)).ToProperInt();

                    //you can process this SMS here

                    if (maxReceivedTimeMilliseconds < smsReceivedTimeMilliseconds) maxReceivedTimeMilliseconds = smsReceivedTimeMilliseconds;
                    cursor.MoveToNext();
                }

                //store the last message read date/time stamp to the application property so that the next time, we can read SMS processed after this date and time stamp. 
                if (totalSMS > 0)
                {
                    Application.Current.Properties["LastSmsReadMilliseconds"] = maxReceivedTimeMilliseconds.ToProperString();
                }
            }
            cursor.Close();
        }
    }
Mohamed Thaufeeq
  • 1,667
  • 1
  • 13
  • 34