我尝试使用此代码通过Intent发送短信:
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("smsto:" + phoneNumber)); intent.putExtra("address",phoneNumber); intent.putExtra("sms_body",messageBody); intent.putExtra("exit_on_sent",true); startActivityForResult(intent,CODE);
然后,我想知道SMS是否已发送,我使用此代码:
public void onActivityResult(int requestCode,int resultCode,Intent intent) { switch (requestCode) { case CODE: if (resultCode == Activity.RESULT_OK) { //Then do... } elseif(resultCode == Activity.RESULT_CANCELED) { // Do... } break; } }
事情是结果始终为0(Activity.RESULT_CANCELED),即使已发送短信也是如此.如何知道短信是否已发送?我想使用手机的短信默认应用程序,而不是创建发送短信的界面.
解决方法
在以下示例中,我们使用ContentObserver来监视SMS提供程序的更新.此Observer在SMS Intent被触发之前创建并启动,并根据目标地址检查Provider更改.创建Observer的Activity必须实现SmsSendObserver.SmsSendListener接口才能接收回调.
Observer的构造函数包含一个超时参数(以毫秒为单位),如果在一段合理的时间后没有发送消息,则允许Observer正确注销.如果需要,可以将其设置为NO_TIMEOUT.但是,如上所述,该类用于“一次性”使用,并且它将取消注册自身并在回调时使成员无效.如果没有回调,stop()方法可用于清理.在任何一种情况下,实例都不再可用,并且对它的任何引用都应设置为null.
示例活动:
public class MainActivity extends Activity implements SmsSendObserver.SmsSendListener { ... private void sendMessage(String phoneNumber,String messageBody) { // This example has a timeout set to 15 seconds new SmsSendObserver(this,phoneNumber,15000).start(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("smsto:" + phoneNumber)); intent.putExtra("address",phoneNumber); intent.putExtra("sms_body",messageBody); intent.putExtra("exit_on_sent",true); startActivity(intent); } public void onSmsSendEvent(boolean sent) { Toast.makeText(this,sent ? "Message was sent" : "Timed out",Toast.LENGTH_SHORT).show(); } }
SmsSendObserver类:
public class SmsSendObserver extends ContentObserver { public static final int NO_TIMEOUT = -1; private static final Handler handler = new Handler(); private static final Uri uri = Uri.parse("content://sms/"); private static final String COLUMN_ADDRESS = "address"; private static final String COLUMN_TYPE = "type"; private static final String[] PROJECTION = { COLUMN_ADDRESS,COLUMN_TYPE }; private static final int MESSAGE_TYPE_SENT = 2; private Context context = null; private ContentResolver resolver = null; private String phoneNumber = null; private long timeout = NO_TIMEOUT; private boolean wasSent = false; private boolean timedOut = false; public SmsSendObserver(Context context,String phoneNumber,long timeout) { super(handler); if (context instanceof SmsSendListener) { this.context = context; this.resolver = context.getContentResolver(); this.phoneNumber = phoneNumber; this.timeout = timeout; } else { throw new IllegalArgumentException( "Context must implement SmsSendListener interface"); } } private Runnable runOut = new Runnable() { @Override public void run() { if (!wasSent) { timedOut = true; callBack(); } } }; public void start() { if (resolver != null) { resolver.registerContentObserver(uri,true,this); if (timeout > NO_TIMEOUT) { handler.postDelayed(runOut,timeout); } } else { throw new IllegalStateException( "Current SmsSendObserver instance is invalid"); } } public void stop() { if (resolver != null) { resolver.unregisterContentObserver(this); resolver = null; context = null; } } private void callBack() { ((SmsSendListener) context).onSmsSendEvent(wasSent); stop(); } @Override public void onChange(boolean selfChange) { if (wasSent || timedOut) return; Cursor cursor = null; try { cursor = resolver.query(uri,PROJECTION,null,null); if (cursor != null && cursor.moveToFirst()) { final String address = cursor.getString(cursor.getColumnIndex(COLUMN_ADDRESS)); final int type = cursor.getInt(cursor.getColumnIndex(COLUMN_TYPE)); if (PhoneNumberUtils.compare(address,phoneNumber) && type == MESSAGE_TYPE_SENT) { wasSent = true; callBack(); } } } finally { if (cursor != null) { cursor.close(); } } } public interface SmsSendListener { // Passes true if the message was sent // Passes false if timed out public void onSmsSendEvent(boolean sent); } }