我正在尝试从我的应用程序发送紧急短信。我必须确保SMS发送成功。
在Android系统启动后并进行检查后,将发送SMS。
因此,我有一个处理BOOT_COMPLETED意向过滤器的服务类。此类进行检查,如果内容正确,则尝试通过另一个“扩展服务”类发送SMS消息
确保成功发送短信后,两个服务(处理启动呼叫的服务和发送短信的服务)都必须退出。
问题1
:如何使我的短信发送功能在超时的情况下被调用,而不会导致应用程序无响应消息?目前,我正在使用此功能(尽管可以正常工作,但我不知道这是否是正确的方法):
Timer mTimer = new Timer();
//wait a small timeout prior to sending the message.
mTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
this.cancel(); //I don't want to run the timer more than once
sms_sender sms = new sms_sender();
sms.sendSMS(phoneNumber, messageText);
}
}, 30000, 30000); //run sendSMS() after 30 seconds
问题2 :如何实现sendSMS功能,以便在意识到上一次尝试失败后每30秒重试一次?
问题3 :在知道短信发送成功后,如何停止两种服务?
这是我的代码不起作用:
public class sms_sender extends Service {
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
final String SENT = "SMS_SENT";
public void sendSMS(final String phoneNumber, final String message, final boolean check_result)
{
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
registerReceiver(new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent arg1) {
if(!check_result)
return;
switch (getResultCode())
{
case Activity.RESULT_OK:
//exit
stopSelf();
return;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
case SmsManager.RESULT_ERROR_NO_SERVICE:
case SmsManager.RESULT_ERROR_NULL_PDU:
case SmsManager.RESULT_ERROR_RADIO_OFF:
//try again in 1 minute
Timer mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
this.cancel(); //no need to run again, if it fails, this exact code will run again
sendSMS(phoneNumber, message, true);
}
}, 60000, 60000);
return;
}
}
}, new IntentFilter(SENT));
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNumber, null, message, sentPI, null);
}
}
当前,该程序在PendingIntent调用上崩溃。我尝试使用私有成员变量在onCreate方法上实现BroadCastReceiver,以便通过onReceive方法再次调用sendSMS()函数,但是onReceive似乎从未运行。
-编辑-
因此,这是我的最终工作代码。我猜我的情况很特殊,因为它不适用于UI线程。我有一个在启动时运行的广播接收器。我正在尝试发送SMS消息,直到成功发送为止。
此Boot Broadcast Receiver启动服务。这是一些代码:
public class service extends Service{
static public service serv;
//member variable. Initializing to null so as to know whether to unregister the service or not
private BroadcastReceiver messageSent = null;
...
...
@Override
public void onStart(Intent intent, int startid)
{
serv=this; //will use this static variable in order to shutdown the service when the message is successfully sent
...
...
if(somethingIsTrue()){
//register receiver
messageSent = new sent_message();
registerReceiver(messageSent, new IntentFilter(sms_sender.INTENT_MESSAGE_SENT));
startMessageServiceIntent(messageText, phoneNumber); //function code can be found on accepted answer
}
}
}
send_message类如下:
public class sent_message extends BroadcastReceiver {
private Context pubCon;
private void startMessageServiceIntent(String message, String receiver) {
Intent i = new Intent(pubCon, sms_sender.class);
i.putExtra(sms_sender.EXTRA_MESSAGE, message);
i.putExtra(sms_sender.EXTRA_RECEIVERS, new String[] { receiver });
pubCon.startService(i);
}
@Override
public void onReceive(Context context, Intent intent) {
pubCon=context;
switch (getResultCode()) {
case Activity.RESULT_OK:
//all went OK, stop the service where this is called from
service.serv.stopSelf();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
case SmsManager.RESULT_ERROR_NO_SERVICE:
case SmsManager.RESULT_ERROR_NULL_PDU:
case SmsManager.RESULT_ERROR_RADIO_OFF:
//try sending the message again after 30s
new Handler().postDelayed(new Runnable(){
@Override
public void run(){
startMessageServiceIntent(service.messageText, service.phoneNumber);
}
}, 30000);
break;
}
}
}
下面是sms_sender类的简化版本(仅接受一个接收器):
public class sms_sender extends IntentService {
public static final String INTENT_MESSAGE_SENT = "message.sent";
public static final String INTENT_MESSAGE_DELIVERED = "message.delivered";
public static final String EXTRA_MESSAGE = "extra.message";
public static final String EXTRA_RECEIVERS = "extra.receivers";
public sms_sender() {
super("sms_sender");
}
private static class IDGenerator {
private static final AtomicInteger counter = new AtomicInteger();
public static int nextValue() {
return counter.getAndIncrement();
}
}
public void sendSMS(String message, String receiver) {
SmsManager sm = SmsManager.getDefault();
PendingIntent sentPI = null;
Intent sentIntent = new Intent(INTENT_MESSAGE_SENT);
int sentID = IDGenerator.nextValue();
sentPI = PendingIntent.getBroadcast(sms_sender.this, sentID, sentIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
try {
sm.sendTextMessage(receiver, null, message, sentPI, null);
} catch (IllegalArgumentException e) {
System.out.println("Illegal argument");
}
}
protected void onHandleIntent(Intent intent) {
String message = intent.getStringExtra(EXTRA_MESSAGE);
String[] receivers = intent.getStringArrayExtra(EXTRA_RECEIVERS);
sendSMS(message, receivers[0]);
}
}
这是我所做的:
public class SMSSender extends IntentService {
public static final String INTENT_MESSAGE_SENT = "message.sent";
public static final String INTENT_MESSAGE_DELIVERED = "message.delivered";
public static final String EXTRA_MESSAGE = "extra.message";
public static final String EXTRA_RECEIVERS = "extra.receivers";
public SMSSender() {
super("SMSSender");
}
private final String TAG = "SendSMS";
private static class IDGenerator {
private static final AtomicInteger counter = new AtomicInteger();
public static int nextValue() {
return counter.getAndIncrement();
}
}
private void sendSMS(String message, String[] receivers) {
SmsManager sm = SmsManager.getDefault();
ArrayList<String> parts = sm.divideMessage(message);
PendingIntent sentPI = null;
PendingIntent deliveredPI = null;
Intent sentIntent = new Intent(INTENT_MESSAGE_SENT);
int sentID = IDGenerator.nextValue();
sentPI = PendingIntent.getBroadcast(SMSSender.this, sentID, sentIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
Intent deliveryIntent = new Intent(INTENT_MESSAGE_DELIVERED);
int deliveredID = IDGenerator.nextValue();
deliveredPI = PendingIntent.getBroadcast(SMSSender.this, deliveredID,
deliveryIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Log.i(TAG, "sending SMS: parts: " + parts.size() + " message: "
+ message);
if (parts.size() > 1) {
ArrayList<PendingIntent> sentIntents = null;
ArrayList<PendingIntent> deliveredIntents = null;
sentIntents = new ArrayList<PendingIntent>();
deliveredIntents = new ArrayList<PendingIntent>();
for (int i = 0; i < parts.size(); i++) {
sentIntents.add(sentPI);
deliveredIntents.add(deliveredPI);
}
for (String receiver : receivers) {
try {
sm.sendMultipartTextMessage(receiver, null, parts,
sentIntents, deliveredIntents);
} catch (IllegalArgumentException e) {
Log.e(TAG, "illegal receiver: " + receiver);
}
}
} else {
for (String receiver : receivers) {
try {
sm.sendTextMessage(receiver, null, parts.get(0), sentPI,
deliveredPI);
} catch (IllegalArgumentException e) {
Log.e(TAG, "illegal receiver: " + receiver);
}
}
}
}
@Override
protected void onHandleIntent(Intent intent) {
String message = intent.getStringExtra(EXTRA_MESSAGE);
String[] receivers = intent.getStringArrayExtra(EXTRA_RECEIVERS);
sendSMS(message, receivers);
}
并使用它:
private void startMessageServiceIntent(String message, String receiver) {
Intent i = new Intent(context, SMSSender.class);
i.putExtra(SMSSender.EXTRA_MESSAGE, message);
i.putExtra(SMSSender.EXTRA_RECEIVERS, new String[] { receiver });
startService(i)
}
请注意,它支持多个接收器,此方法未演示/使用。
记住清单中的内容:
<uses-permission android:name="android.permission.SEND_SMS" />
<service android:name="your.package.SMSSender" android:enabled="true" />
(可选)您可以侦听何时发送和/或传递消息:
@Override
protected void onCreate() {
...
// ---when the SMS has been sent---
private BroadcastReceiver messageSent; // <- stored as a field
messageSent = new SentMessage();
registerReceiver(messageSent, new IntentFilter(SMSSender.INTENT_MESSAGE_SENT));
// ---when the SMS has been delivered---
private BroadcastReceiver messageDelivered; // <- stored as a field
messageDelivered = new MessageDelivered();
registerReceiver(messageDelivered, new IntentFilter(
SMSSender.INTENT_MESSAGE_DELIVERED));
}
@Override
protected void onDestroy() { // remember to unregister
unregisterReceiver(messageSent);
unregisterReceiver(messageDelivered );
}
我知道这并不能说明您所有问题的答案,但我希望这已足够。
编辑: 添加了我的messageSent和messageDelivered实现
这些特定于我的实现,因此包括一些您无法使用的代码,仅用于演示。
讯息已发送:
public class SentMessage extends BroadcastReceiver {
private final String TAG = "SentMessage";
@Override
public void onReceive(Context context, Intent intent) {
long _id = intent.getLongExtra(EXTRA_ID, -1);
long protocol_id = intent.getLongExtra(EXTRA_PROTOCOL, -1);
Log.d(TAG, "SentMessage");
switch (getResultCode()) {
case Activity.RESULT_OK:
Log.d(TAG, "RESULT_OK");
if (MessageData.sentMessage(_id, protocol_id)) {
try {
Database.messageSent(_id);
} catch (DatabaseRowNotFoundException e) {
Log.e(TAG, e.toString(), e);
}
}
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Log.d(TAG, "RESULT_ERROR_GENERIC_FAILURE");
MessageData.postponeMessage(_id);
ApplicationData.hasSignal(false);
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Log.d(TAG, "RESULT_ERROR_NO_SERVICE");
MessageData.postponeMessage(_id);
ApplicationData.hasSignal(false);
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Log.d(TAG, "RESULT_ERROR_NULL_PDU");
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Log.d(TAG, "RESULT_ERROR_RADIO_OFF");
MessageData.postponeMessage(_id);
ApplicationData.hasSignal(false);
break;
}
}
讯息已传送:
public class DeliveredMessage extends BroadcastReceiver {
private final String TAG = "DeliveredMessage ";
@Override
public void onReceive(Context context, Intent intent) {
long _id = intent.getLongExtra(EXTRA_ID, -1);
long protocol_id = intent.getLongExtra(EXTRA_PROTOCOL, -1);
switch (getResultCode()) {
case Activity.RESULT_OK:
if (_id != -1 && MessageData.deliveredMessage(_id, protocol_id)) {
try {
Database.messageDelivered(_id);
Cursor messageCursor = Database.getCursorByID(MessageOutboxContentProvider.CONTENT_URI, MessageOutboxContentProvider._ID, _id);
messageCursor.close();
} catch (DatabaseRowNotFoundException e) {
Log.e(TAG, e.toString(), e);
}
}
break;
case Activity.RESULT_CANCELED:
break;
}
}
}
我也需要可靠的发送,因此请保留对数据库中所有未决消息的引用,我会经常扫描这些消息以查找延迟的消息。如果没有无线电,消息将被推迟,或者由于某种原因发送失败。
我还结合使用GCM和SMS来使消息尽快传递,同时使用两个通道发送消息。
Edit2: 哦,还可以解决问题,无论如何我们几乎都在那儿:
问题1: 由于使用IntentService,因此发送是在后台完成的。
您只希望发送在延迟后发生一次,因此您应该这样做:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// send sms
}
}, delay);
问题2:
很容易,当您发送的消息广播检测到错误时,请执行上述方法。除了接收者和消息之外,您还可以添加其他信息,计算到目前为止的重试次数,这样您就有机会停止发送/重试循环。
问题3:
发送是一种意图服务,因此发送本身会停止。对于其他服务,我认为最简单的方法是发送公共广播,该广播由您的主要活动接听。这样,您就可以在适当的位置获得该服务并停止该服务。
我的应用程序通过SmsManager.sendMultipartTextMessage发送短信,然后通知服务器短信发送的状态。 一切正常,但Yota操作员有问题。短信不会发送到 MTS 运营商的手机。Yota运营商的员工声称MTS运营商阻止接收来自Yota的消息。 这不是我们的问题,但Android系统说,这样的短信成功交付。我们无法从其他手机重新发送此类短信,因为我们的系统认为它们已经成功发送。
本文向大家介绍Twilio 发送短信,包括了Twilio 发送短信的使用技巧和注意事项,需要的朋友参考一下 示例 要使用Twilio和Python发送您的第一条SMS,您只需要Twilio-Python帮助程序库即可开始。
egg 发送短信逻辑 service 'use strict'; const Service = require('egg').Service; class UserService extends Service { /** * 发送验证码 */ async sendCode() { //1. 获取用户手机号 const { phone } = this
我正在尝试使用亚马逊SNS发送消息,但它显示了非典型的行为。它向一些号码发送消息,而向另一些号码发送消息,也可能不发送消息。 我正在使用publish API直接为OTPs发送SMS而不使用主题。有什么办法我可以得到他们的送货状态吗?区域/DND是否会影响交货。这是为了印度数字。我使用的是事务性消息。
问题内容: 从Java应用程序发送和接收短信的可能方法是什么? 问题答案: 如果您想要的只是简单的通知,许多运营商都支持通过电子邮件发送短信;通过电子邮件查看短信