"真"测试短信接收机

时间:2014-03-10 20:50:59

标签: android android-intent sms broadcastreceiver

我有一个SmsReceiver我想在设备上测试真实,但是我不愿意将一堆真正的短信发送到我的设备上,这会堆积我的电话费; - )

所以我认为我必须能够使用动作intent,短信数据和发送短信所需的所有其他内容来RECEIVED_SMS。在谷歌快速浏览之后,我结束了这里:http://blog.dev001.net/post/14085892020/android-generate-incoming-sms-from-within-your-app。 我从这篇文章中得到了一些想法并制作了我的杀手级Android应用程序,用于在设备上创建和“发送”短信用于测试目的,我必须说它有点像魅力,除了我的接收器onReceive不是调用后,发送的短信直接进入收件箱。我知道我的接收器工作,如果我发送一个真正的短信到我的设备它触发,如果我发送短信从DDMS到模拟器它也会触发,所以这应该没问题。

那么我有没有permissions,一些Intent.putExtras或其他东西?任何提示都非常有用,如果能够实现这一点,它将有助于我测试和开发我的应用程序。

清单中的接收者:

<receiver android:name=".SmsReceiver">
     <intent-filter android:priority="1000"> 
        <action android:name="android.provider.Telephony.SMS_RECEIVED"/> 
     </intent-filter> 
</receiver>

清单中的权限(接收申请):

<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.VIBRATE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />  

清单中的权限(发送应用程序):

<uses-permission android:name="android.permission.BROADCAST_SMS"/>

还应该提到在LogCat或控制台中没有出现任何错误。

3 个答案:

答案 0 :(得分:1)

这就是我的接收器在清单中的样子:

<receiver android:name="com.mike.broadcastexample.BroadcastReceiverClass" android:exported="true" > 
            <intent-filter android:priority="999" > 
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter> 
        </receiver>

我唯一要做的就是将 android:priority设置为999 并添加 android:exported =&#34; true&#34; < / p>

这些是我用于该应用的唯一权限:

    <uses-permission android:name="android.permission.WRITE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />

我的应用程序也遇到了同样的问题,它是HTC ONE,它有Android 4.3但是在对这个接收器做了一些改动后,它的工作绝对完美。

你也可以尝试一下。

答案 1 :(得分:1)

使用以下接收方声明还要确保主要包中存在 SMsReceiver ,否则提供完整路径&#34; * 路径 / SmsReceiver *&#34;这里path表示完整的包路径。

 <receiver
            android:name=".SmsReceiver"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS" >
            <intent-filter android:priority="5822" >
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

此外,所有权限似乎都很好,就像您发送短信一样,只包括

<uses-permission android:name="android.permission.SEND_SMS" />

答案 2 :(得分:0)

我要说的是,这里有三种可能性,每种可能性都有自己的用例和真实性级别。

首先,显然,您可以将真实的SMS消息发送到手机。如果您当前的电话计划不够用,可以考虑购买便宜的预付费SIM卡,并获得不错的SMS价。另一个选择是use Skype to send SMS,它比使用真实设备更便宜,更方便。

其次,在模拟器上或通过真实设备上的ADB进行测试。据我所知,这与接收真实的短信“一样”。好处当然是它是免费的,而且非常方便,因为它使您可以比在设备上更轻松地操作SMS参数。

第三,一旦您对以上两个测试级别感到满意,请考虑将实际的大部分逻辑从SMS_RECEIVED分解为另一种方法,而不是实际发送和接收真实的onReceive()广播,然后可以手动调用它。

SmsBroadCastReceiver.java

public class SmsBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "SmsBroadcastReceiver";


    public class SmsMessageData{
        public String body;
        public String sender;
        public long timestamp;
    }


    public void onReceive(final Context context, Intent intent) {
        SmsMessageData data = parseSmsMessage(intent.getExtras());
        handleSmsMessageData(context, data);
    }

    public void handleSmsMessageData(Context context, SmsMessageData data) {
        // Do what you want with the data, for example store it in your database
        // and show a notification. Note that data might be null!
    }


    private SmsMessageData parseSmsMessage(Bundle intentExtras) {
        if (intentExtras != null) {
            Object[] smsArray = (Object[]) intentExtras.get("pdus");

            if (smsArray != null) {
                String format = intentExtras.getString("format");
                StringBuilder body = new StringBuilder("");
                String sender = "";
                long timestamp = System.currentTimeMillis();

                for (Object sms : smsArray) {
                    android.telephony.SmsMessage smsMessage = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? android.telephony.SmsMessage.createFromPdu((byte[]) sms, format) : android.telephony.SmsMessage.createFromPdu((byte[]) sms);
                    body.append(smsMessage.getMessageBody());
                    sender = smsMessage.getOriginatingAddress();
                    timestamp = smsMessage.getTimestampMillis();
                }

                SmsMessageData result = new SmsMessageData();
                result.body = String.valueOf(body);
                result.sender = sender;
                result.timestamp = timestamp;
                return result;
            }
        }

        return null;
    }
}

您可以通过调用

轻松地模拟接收消息
new SmsBroadcastReceiver().handleSmsMessageData(this, data);

并从应用程序中传递所需的任何数据。

因此,回顾一下,前两个测试级别涉及以不同程度的真实性测试您的基本SMS解析逻辑,而第三个级别是测试BroadcastReceiver实际执行后的操作的一种更抽象的方式已经解析了收到的短信。