如何在Android中使用带有自定义线程ID的SmsManager发送短信? [英] How to send sms with SmsManager with customised thread ID in Android?

查看:92
本文介绍了如何在Android中使用带有自定义线程ID的SmsManager发送短信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个自定义线程ID为10001的短信。我怎样才能做到这一点 ?原因是因为我需要实现删除短信功能,删除特定短信线程的唯一方法是通过线程ID或电话号码,并且在这个时间点获取电话号码是不可能的,因此需要定义自定义线程ID在我发送短信时。

I would like to create an SMS with a customised thread ID say "10001". How can I do that ? Reason is because I needed to implement a delete SMS function and the only way to delete a specific SMS thread is either via thread ID OR phone number and getting phone number isnt exactly possible at this point of time hence the needed to define a custom thread ID in my sending of SMS.

到目前为止,我只能获得正常的短信工作代码:

I was only able to get a normal SMS working code thus far as below:

    SmsManager smsManager = SmsManager.getDefault();
    smsManager.sendTextMessage("+1 203 514 6584", null, "HI Greg! ", null, null);

提前感谢您的帮助!

推荐答案

SmsObserver 类是 ContentObserver ,它在<$上注册c $ c> content:// sms / Uri 并根据收件人的地址和邮件正文检查SMS表中的更改以检索指定的线程传出SMS消息的ID。该类提供了一个接口,您的发送类需要实现该接口,以便在确定时接收线程ID,因为这将异步发生。

The SmsObserver class is a ContentObserver that registers itself on the content://sms/ Uri and checks changes in the SMS table against the recipient's address and message body to retrieve the assigned thread ID for an outgoing SMS message. The class offers an interface that your sending class needs to implement in order to receive the thread ID when it's determined, as this will happen asynchronously.

public class SmsObserver extends ContentObserver {
    private static final Handler handler = new Handler();
    private static final Uri uri = Uri.parse("content://sms/");

    private final Context context;
    private final ContentResolver resolver;
    private final String address;
    private final String body;

    public interface OnSmsSentListener {
        public void onSmsSent(int threadId);
    }

    public SmsObserver(Context context, String address, String body) {
        super(handler);

        if (context instanceof OnSmsSentListener) {
            this.context = context;
            this.resolver = context.getContentResolver();
            this.address = address;
            this.body = body;
        }
        else {
            throw new IllegalArgumentException(
                "Context must implement OnSmsSentListener interface");
        }
    }

    public void start() {
        if (resolver != null) {
            resolver.registerContentObserver(uri, true, this);
        }
        else {
            throw new IllegalStateException(
                "Current SmsObserver instance is invalid");
        }
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        Cursor cursor = null;

        try {
            cursor = resolver.query(uri, null, null, null, null);

            if (cursor != null && cursor.moveToFirst()) {
                final int type = cursor.getInt(
                    cursor.getColumnIndex(Telephony.Sms.TYPE));

                if(type == Telephony.Sms.Sent.MESSAGE_TYPE_SENT) {
                    final String address = cursor.getString(
                        cursor.getColumnIndex(Telephony.Sms.ADDRESS));
                    final String body = cursor.getString(
                        cursor.getColumnIndex(Telephony.Sms.BODY));
                    final int threadId = cursor.getInt(
                        cursor.getColumnIndex(Telephony.Sms.THREAD_ID));

                    if (PhoneNumberUtils.compare(address, this.address) &&
                        body.equals(this.body)) {

                        ((OnSmsSentListener) context).onSmsSent(threadId);
                        resolver.unregisterContentObserver(this);
                    }
                }
            }
        }
        finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }
}

这个实例需要在发送消息之前启动,并且线程ID将被传递到发送类的接口方法实现中。例如,如果您在点击按钮时从活动发送:

An instance of this needs to be started before the message is sent, and the thread ID will be passed into the sending class's interface method implementation. For example, if you're sending from an Activity upon clicking a Button:

public class MainActivity extends Activity
    implements SmsObserver.OnSmsSentListener {
    ...

    public void onClick(View v) {
        String address = "+1 234 567 8900";
        String body = "HI Greg! ";

        new SmsObserver(this, address, body).start();

        SmsManager smsManager = SmsManager.getDefault();
        smsManager.sendTextMessage(address, null, body, null, null);
    }

    @Override
    public void onSmsSent(int threadId) {
        // Here's the thread ID.
    }
}

请注意,您需要 READ_SMS 权限。

可以从Lollipop开始提供替代方案。已发送邮件的URI将作为 String 附加附加到中的 Intent PendingIntent 作为 sendTextMessage()方法中的第四个参数传递。额外的将具有键uri,并且可以被解析为 Uri ,然后可以将其用于查询 ContentResolver 以检索如上所示的线程ID。

A possible alternative is available starting in Lollipop. The URI of the sent message will be attached as a String extra to the Intent from the PendingIntent passed as the fourth argument in the sendTextMessage() method. The extra will have the key "uri", and can be parsed as a Uri, which can then be used in a query on ContentResolver to retrieve the thread ID as shown above.

例如,如果使用<$ c对于结果,$ c> BroadcastReceiver , sendTextMessage()调用将是这样的:

For example, if using a BroadcastReceiver for the result, the sendTextMessage() call would be like so:

Intent sentIntent = ...
PendingIntent sentPi = PendingIntent.getBroadcast(context, 0, sentIntent, 0);

SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(address, null, body, sentPi, null);

在Receiver中检索额外费用就像这样:

And retrieving the extra in the Receiver would be like so:

public class SmsResultReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        ...

        String uriString = data.getStringExtra("uri");
        Uri uri = Uri.parse(uriString);

        // Query as shown above in the ContentObserver
        ...
    }
}

这篇关于如何在Android中使用带有自定义线程ID的SmsManager发送短信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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