用户离开活动后如何接收个人 SMS 发送/传递的 SMS 反馈
Posted
技术标签:
【中文标题】用户离开活动后如何接收个人 SMS 发送/传递的 SMS 反馈【英文标题】:How to receive SMS sent/delivered feedback for individual SMS after user left activity 【发布时间】:2012-05-12 22:32:52 【问题描述】:我有一个提供 SMS 消息的应用程序。短信数据存储在应用数据库中。 该应用程序支持向多个联系人发送消息,因此在发送 SMS 时,我会动态注册一个不同的 BroadcastReceiver 以侦听是否发送了每条 SMS(我使用字符串中的每个电话号码来标识 IntentFilter 中的操作)。
收到确认后将短信写入数据库。
问题是,如果用户在“已发送”Intent 被广播之前离开活动,BroadcastReceivers 将丢失,我无法再捕获“已发送”Intent,因此数据库不会更新。我选择的一种解决方法是实现 onKeyDown() 以防止用户在所有 Intent 被广播之前关闭活动,但此解决方案仅适用于“返回”按钮 - 无法捕获“主页”按钮事件。
这是我的代码:
public void sendSMS(String[] phoneNumbers, String message)
final String currentMessage = message;
SmsManager sms = SmsManager.getDefault();
ArrayList<String> parts = sms.divideMessage(message);
for(int i=0; i<phoneNumbers.length; i++)
for(int j=0; j<parts.size(); j++)
BroadcastReceiver sent = new BroadcastReceiver()
public void onReceive(Context arg0, Intent arg1)
String[] arg = arg1.getAction().split(KEY_SMS_SENT);
String phoneNo = Utils.setSimpleFormatNumber(arg[1]);
String count = arg[0];
String parts = count.split(KEY_SMS_PART_NO)[0];
String partNo = count.split(KEY_SMS_PART_NO)[1];
sentReceivers.remove(this);
unregisterReceiver(this);
switch (getResultCode())
case Activity.RESULT_OK:
if(parts.equals(partNo))
Toast.makeText(getBaseContext(), context.getString(R.string.sms_sent_message),
Toast.LENGTH_SHORT).show();
dbAdapter.createSentSMS(KEY_SMS_TYPE_SENT, phoneNo, currentMessage, Utils.getTimeStamp());
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
if(parts.equals(partNo))
Toast.makeText(getBaseContext(), context.getString(R.string.sms_generic_failure_message),
Toast.LENGTH_SHORT).show();
dbAdapter.createSentSMS(KEY_SMS_TYPE_FAILED, phoneNo, currentMessage, Utils.getTimeStamp());
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
if(parts.equals(partNo))
Toast.makeText(getBaseContext(), context.getString(R.string.sms_no_service_message),
Toast.LENGTH_SHORT).show();
dbAdapter.createSentSMS(KEY_SMS_TYPE_FAILED, phoneNo, currentMessage, Utils.getTimeStamp());
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
if(parts.equals(partNo))
Toast.makeText(getBaseContext(), context.getString(R.string.sms_null_pdu_message),
Toast.LENGTH_SHORT).show();
dbAdapter.createSentSMS(KEY_SMS_TYPE_FAILED, phoneNo, currentMessage, Utils.getTimeStamp());
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
if(parts.equals(partNo))
Toast.makeText(getBaseContext(), context.getString(R.string.sms_radio_off_message),
Toast.LENGTH_SHORT).show();
dbAdapter.createSentSMS(KEY_SMS_TYPE_FAILED, phoneNo, currentMessage, Utils.getTimeStamp());
break;
;
registerReceiver(sent, new IntentFilter(String.valueOf(parts.size()-1) + KEY_SMS_PART_NO + String.valueOf(j) + KEY_SMS_SENT + phoneNumbers[i]));
//I add the BroadcastReceiver-s to a Vector in order to keep track of them
sentReceivers.add(sent);
//I use an IntentService to do the actual sending
Intent intent = new Intent(context, SMSSendService.class);
intent.putExtra(KEY_SELECTED_PHONE_NUMBERS, phoneNumbers);
intent.putExtra(KEY_SMS_MESSAGE, message);
intent.putExtra(KEY_ACTION, KEY_REQUEST_SEND_SMS);
startService(intent);
这是 IntentService 中的代码:
public void sendSMS(String phoneNo, String message, SmsManager sms)
ArrayList<String> parts = sms.divideMessage(message);
ArrayList<PendingIntent> sentPIs = new ArrayList<PendingIntent>();
for(int i=0; i<parts.size(); i++)
sentPIs.add(PendingIntent.getBroadcast(context, 0, new Intent(String.valueOf(parts.size()-1) + KEY_SMS_PART_NO + String.valueOf(i) + KEY_SMS_SENT + phoneNo), 0));
sms.sendMultipartTextMessage(phoneNo, null, parts, sentPIs, deliveredPIs);
【问题讨论】:
【参考方案1】:您可以创建一个服务(不是 IntentService),您可以在其中实例化所有广播接收器并执行发送 SMS 逻辑。这样,您的 SMS-es 将在后台发送,您可以拦截发送/传递的广播。
【讨论】:
以上是关于用户离开活动后如何接收个人 SMS 发送/传递的 SMS 反馈的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法拦截 Android SMS 发送以转发到不同的传输?
当活动屏幕首次在 Android Studio 上加载时,如何在隐藏的背景中发送带有当前位置数据的 SMS 文本消息?