我想创建一个带有自定义线程ID的短信,说" 10001"。我怎样才能做到这一点 ?原因是因为我需要实现删除短信功能,删除特定短信线程的唯一方法是通过线程ID或电话号码,并且在这个时间点获取电话号码是不可能的,因此需要定义自定义线程ID在发送短信时。
到目前为止,我只能获得正常的SMS工作代码:
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage("+1 203 514 6584", null, "HI Greg! ", null, null);
提前感谢您的帮助!
答案 0 :(得分:2)
SmsObserver
类是ContentObserver
,它在content://sms/
Uri
上注册自己,并根据收件人的地址和邮件正文检查SMS表中的更改检索传出SMS消息的已分配线程ID。该类提供了一个接口,您的发送类需要实现该接口,以便在确定后接收线程ID,因为这将异步发生。
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将被传递到发送类的接口方法实现中。例如,如果您在点击Activity
时从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,如上所示。
例如,如果使用BroadcastReceiver
作为结果,那么sendTextMessage()
调用就是这样:
Intent sentIntent = ...
PendingIntent sentPi = PendingIntent.getBroadcast(context, 0, sentIntent, 0);
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(address, null, body, sentPi, null);
在Receiver中检索额外内容就像这样:
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
...
}
}