问题描述
我有一个SmsReceiver
,我想在设备上测试真实,但是我不愿意发送一堆真正的短信到我的设备堆叠我的电话费;-)
所以我想,我必须能够踢的的intent
与行动RECEIVED_SMS
,短信的数据和发送短信所需的所有其他的东西。
在谷歌快速浏览之后,我最终来到这里: : 。
我从这篇文章中获取了一些想法并制作了我的杀手级Android应用程序,用于在设备上创建和“发送”短信用于测试目的,我必须说它onReceive
像魅力,除了我的接收器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或控制台中没有出现任何错误。
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 =“true”
这些是我用于应用程序的唯一权限:
<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但是在对这个接收器做了一些改动后,它的工作绝对完美。
你也可以尝试一下。
2楼
使用以下接收器声明还要确保您的SMsReceiver存在于主包中,否则提供完整路径“ * path / SmsReceiver *”此处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" />
3楼
我要说这里有三种可能性,每种都有自己的用例和真实性。
首先,显然,您可以向手机发送真正的短信。 如果您当前的电话计划不充分,请考虑购买价格便宜的预付费SIM卡。 另一个选择是 ,这可能比使用真实设备更便宜,更方便。
其次,在仿真器上或通过真实设备上的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解析逻辑,具有不同程度的真实性,第三级是一种更抽象的方式来测试一旦解析收到的SMS后你的BroadcastReceiver
实际做了什么。