Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receiving SMS with MonoDroid

Edit: This is now resolved - posting solution here in case someone needs it in future or anyone can suggest a better way of doing this. I removed the intent stuff from my manifest and just setup the BroadcastReceiver in my SmsReceiver class. This now works.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Util;
using Android.Telephony;

namespace dummyAndroid
{
    [BroadcastReceiver(Enabled = true, Label = "SMS Receiver")]
    [IntentFilter(new string[] { "android.provider.Telephony.SMS_RECEIVED" })] 
    public class SmsReceiver : Android.Content.BroadcastReceiver 
    {
        public static readonly string INTENT_ACTION = "android.provider.Telephony.SMS_RECEIVED"; 

        public override void OnReceive(Context context, Intent intent)
        {
            if (intent.Action == INTENT_ACTION)
            {
                StringBuilder buffer = new StringBuilder();
                Bundle bundle = intent.Extras;

                if (bundle != null)
                {
                    Java.Lang.Object[] pdus = (Java.Lang.Object[])bundle.Get("pdus");

                    SmsMessage[] msgs;
                    msgs = new SmsMessage[pdus.Length];

                    for (int i = 0; i < msgs.Length; i++)
                    {
                        msgs[i] = SmsMessage.CreateFromPdu((byte[])pdus[i]);

                        Log.Info("SmsReceiver", "SMS Received from: " + msgs[i].OriginatingAddress);
                        Log.Info("SmsReceiver", "SMS Data: " + msgs[i].MessageBody.ToString());
                    }

                    Log.Info("SmsReceiver", "SMS Received");
                }
            } 
        }
    }
}

I'm writing an app that sends/receives SMS messages and have got sending working via the SMS Mananger.

I'm now trying to receive SMS in Mono for Android and am new to Android development so am probably doing something wrong!

I have added the following to my manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="com.me.dummyAndroid" android:versionCode="1" android:versionName="1">
  <uses-sdk android:targetSdkVersion="8" />
  <application 
        android:label="meAndroidSMS"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
    <receiver android:name=".SmsReceiver">
      <intent-filter>
        <action android:name=
                    "android.provider.Telephony.SMS_RECEIVED" />
      </intent-filter>
    </receiver>
  </application>
  <uses-permission android:name="android.permission.SEND_SMS" />
  <uses-permission android:name="android.permission.RECEIVE_SMS" />
  <uses-permission android:name="android.permission.READ_SMS" />
</manifest>

I then created a new class called SmsReceiver.cs which I've added the function onReceive into but there doesn't appear to be the getExtras function within intent which according to the online tutorial I read I would need (http://www.techques.com/question/1-3542320/IPhone-Android-SMS-intercept-and-redirection-to-an-application.).

namespace dummyAndroid
{
    class SmsReceiver
    {
        public void onReceive(Context context, Intent intent)
        {
            Bundle bundle = intent.getExtras();



        }
    }
}

I appreciate I'm in a bit over my head on Android and MonoDroid for sure but maybe someone can point me in the right direction!

like image 602
AdamantUK Avatar asked Jan 07 '13 16:01

AdamantUK


Video Answer


1 Answers

I have some working code here (I can't remember the source, but I think it was someone associated with Xamarin who wrote this sample), which displays a Toast when an SMS is recieved.

using System.Text;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Util;
using Android.Widget;
using Android.Telephony;
using Environment = System.Environment;

namespace MonoDroid.SMSFun
{
    [BroadcastReceiver(Enabled = true, Label = "SMS Receiver")]
    [IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" })] 
    public class SMSBroadcastReceiver : BroadcastReceiver
    {
        private const string Tag = "SMSBroadcastReceiver";
        private const string IntentAction = "android.provider.Telephony.SMS_RECEIVED"; 

        public override void OnReceive(Context context, Intent intent)
        {
            Log.Info(Tag, "Intent received: " + intent.Action);

            if (intent.Action != IntentAction) return;

            var bundle = intent.Extras;

            if (bundle == null) return;

            var pdus = bundle.Get("pdus");
            var castedPdus = JNIEnv.GetArray<Java.Lang.Object>(pdus.Handle);

            var msgs = new SmsMessage[castedPdus.Length];

            var sb = new StringBuilder();

            for (var i = 0; i < msgs.Length; i++)
            {
                var bytes = new byte[JNIEnv.GetArrayLength(castedPdus[i].Handle)];
                JNIEnv.CopyArray(castedPdus[i].Handle, bytes);

                msgs[i] = SmsMessage.CreateFromPdu(bytes);

                sb.Append(string.Format("SMS From: {0}{1}Body: {2}{1}", msgs[i].OriginatingAddress,
                                        Environment.NewLine, msgs[i].MessageBody));
            }

            Toast.MakeText(context, sb.ToString(), ToastLength.Long).Show();
        }
    }
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="monodroid.smsfun" android:versionCode="1" android:versionName="1.0">
  <uses-sdk android:targetSdkVersion="8" />
  <application android:label="SMSFun">
  </application>
  <uses-permission android:name="android.permission.RECEIVE_SMS" />
</manifest>
like image 60
Cheesebaron Avatar answered Oct 24 '22 00:10

Cheesebaron