使用MonoDroid接收短信

5

编辑:此问题已解决 - 在此发布解决方案,以防将来有人需要或任何人可以建议更好的方法。我从清单中删除了意图部分,并在我的SmsReceiver类中设置了BroadcastReceiver。现在它可以工作了。

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

我正在编写一个发送/接收短信的应用程序,通过SMS Manager已经实现了发送功能。

现在我想在Mono for Android中接收短信,但由于我是Android开发的新手,可能做错了什么!

我已经将以下内容添加到我的清单中

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

接着,我创建了一个名为SmsReceiver.cs的新类,并将onReceive函数添加到其中,但是intent中似乎没有getExtras函数,根据我阅读的在线教程(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();



        }
    }
}

我知道在Android和MonoDroid方面,我可能有点力不从心,但也许有人能指点我一下!

1个回答

9

我这里有一些可用的代码(我记不清源头了,但我认为是与Xamarin有关的某个人编写的示例),当接收到短信时会显示一个Toast。

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>

谢谢,这比我最后凑巧做出来的方式要干净整洁多了!我将根据这个重构我的代码。 - AdamantUK
@Cheesebaron,你能否请看一下我的问题?我正在使用你的代码,但是有一个错误我无法解决。http://stackoverflow.com/questions/27864321/cannot-cast-from-source-type-to-destination-type-xamarin-studio - jay_t55
@Cheesebaron 我有一个类似的应用程序,使用“android.provider.Telephony.SMS_RECEIVED”来获取交付状态,但在行var pdus = bundle.Get(“pdus”);上我得到了null_Reference异常,实际上bundle中没有pdus,我尝试使用pdu,但下一行遇到了转换异常。 请告诉我我错在哪里,当获取交付状态时,我必须拥有接收方号码和消息,这对我非常重要。 - Mahdi Tahsildari
不确定出了什么问题。我上次看这个已经是4年前的事了。你最好的选择是创建一个新的Stack Overflow问题,描述你的问题。 - Cheesebaron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接