Mohamed Thaufeeq
Mohamed Thaufeeq

Reputation: 1677

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

Upvotes: 0

Views: 207

Answers (1)

Mohamed Thaufeeq
Mohamed Thaufeeq

Reputation: 1677

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();
        }
    }

Upvotes: 1

Related Questions