Forum Xamarin.Android

How to get information when an SMS is send?

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.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?

Best Answer

  • thaufeethaufee ✭✭
    Accepted 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();
            }
        }
    

Answers

  • thaufeethaufee Member ✭✭
    Accepted 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();
            }
        }
    
  • jezhjezh Member, Xamarin Team Xamurai

    Congrats, and thanks for sharing the answer.

Sign In or Register to comment.