我想创建一 strip 有自定义线程 ID(例如“10001”)的 SMS。我怎样才能做到这一点 ?原因是因为我需要实现删除短信功能,而删除特定短信线程的唯一方法是通过线程 ID 或电话号码,而此时获取电话号码并不完全可能,因此需要定义自定义线程 ID在我发送短信时。
到目前为止,我只能获得正常的短信工作代码,如下所示:
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage("+1 203 514 6584", null, "HI Greg! ", null, null);
预先感谢您的帮助!
最佳答案
SmsObserver
类是 ContentObserver
在 content://sms/
上注册自己Uri
并根据收件人地址和消息正文检查 SMS 表中的更改,以检索为传出 SMS 消息分配的线程 ID。该类提供了一个接口(interface),您的发送类需要实现该接口(interface),以便在确定线程 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 将被传递到发送类的接口(interface)方法实现中。例如,如果您从 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()
中的第四个参数传递方法。额外的会有 key "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);
在接收器中检索额外的内容将如下所示:
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
...
}
}
关于java - 如何在Android中使用SmsManager发送具有自定义线程ID的短信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36097510/