通过一个Intent发送短信和知道短信已发送或不 [英] Sending SMS via an Intent and know if the SMS has been sent or not

查看:189
本文介绍了通过一个Intent发送短信和知道短信已发送或不的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过这个code一个Intent发送短信:

I tried to send an sms via an Intent with this code:

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);

然后,我想知道,如果短信已发送或没有,我用这个code:

Then, I want to know if the SMS has been sent or not and I use this code:

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),即使短信已发送。我怎么能知道短信已发送或不?我想用手机的短信默认的应用程序,而不是创建一个发送短信的界面。

The thing is the result is always 0 (Activity.RESULT_CANCELED), even when the SMS has been sent. How can I know if the SMS has been sent or not ? I want to use the SMS default app of the phone, not create an interface that sends SMS.

推荐答案

在下面的例子中,我们使用ContentObserver监视更新到SMS提供。这名观察员创建并启动短信意图是发射前,并检查针对的目标地址的供应商的变化。创建观察者必须实现 SmsSendObserver.SmsSendListener 接口来接收回调的活动。

In the following example, we use a ContentObserver to monitor updates to the SMS Provider. This Observer is created and started before the SMS Intent is fired, and checks the Provider changes against the destination address. The Activity that creates the Observer must implement the SmsSendObserver.SmsSendListener interface to receive the callback.

观察者的构造包括暂停参数(以毫秒为单位),以便如果消息的一段合理时间后未寄出的观察是正确的注册。这可以被设置为了no_timeout 如果需要的话。然而,类,如写的,是为一炮打响的使用,它会自行注销并在回调抵消成员。该停止()方法可以使用​​,如果没有回调发生清理。在两种情况下,实例不再可用,且任何对它的引用应该被设置为空。

The Observer's constructor includes a timeout parameter (in milliseconds) to allow the Observer to be properly unregistered if the message is not sent after a reasonable amount of time. This can be set to NO_TIMEOUT if desired. However, the class, as written, is meant for "one shot" use, and it will unregister itself and nullify members upon callback. The stop() method can be used to clean up if no callback occurs. In either case, the instance is no longer usable, and any reference to it should be set to 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 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, new String[]{COLUMN_ADDRESS, COLUMN_TYPE},
                                    null, null, null);

            if (cursor != null && cursor.moveToFirst())
            {
                String address = cursor.getString(cursor.getColumnIndex(COLUMN_ADDRESS));
                int type = cursor.getInt(cursor.getColumnIndex(COLUMN_TYPE));

                if (phoneNumber.equals(address) && MESSAGE_TYPE_SENT == type)
                {
                    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);
    }
}

请注意,这是不能保证工作无处不在,如SMS实现可以有所不同,尤其是在旧的Andr​​oid版本。

Please note that this is not guaranteed to work everywhere, as SMS implementations can vary, especially on older Android versions.

这篇关于通过一个Intent发送短信和知道短信已发送或不的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆