android – 通过Intent发送短信,并知道短信是否已被发送

我尝试使用此代码通过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的构造函数包含一个超时参数(以毫秒为单位),如果在一段合理的时间后没有发送消息,则允许Obse​​rver正确注销.如果需要,可以将其设置为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);
    }
}

相关文章

这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的...
这篇文章主要介绍“Android岛屿数量算法怎么使用”的相关知识...
本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,...
本文小编为大家详细介绍“Android数据压缩的方法是什么”,内...