这是我所做的:
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); } } }}@Overrideprotected 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" />
(可选)您可以侦听何时发送和/或传递消息:
@Overrideprotected 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));}@Overrideprotected void onDestroy() { // remember to unregister unregisterReceiver(messageSent); unregisterReceiver(messageDelivered );}
我知道这并不能说明您所有问题的答案,但我希望这已足够。
编辑: 添加了我的messageSent和messageDelivered实现
这些特定于我的实现,因此包括一些您无法使用的代码,仅用于演示。
讯息已发送:
public class SentMessage extends BroadcastReceiver {private final String TAG = "SentMessage";@Overridepublic 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 ";@Overridepublic 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:
发送是一种意图服务,因此发送本身会停止。对于其他服务,我认为最简单的方法是发送公共广播,该广播由您的主要活动接听。这样,您就可以在适当的位置获得该服务并停止该服务。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)