我已经为 registerContentObserver
设置了后台服务,以便在发送 SMS 时得到通知。收到此事件后,我会增加一个变量以了解发送的消息数。这按预期工作。
当有人发送超过 140 个字符的 SMS 时,移动运营商会将其视为多条 SMS,但似乎我只收到 1 个已发送消息的回调。这导致我的应用错过了对某些消息的计数。
有没有什么正确的方法可以知道实际发送了多少消息?
最佳答案
当应用程序负责将自己的消息写入 Provider 时,它很可能会一次写入整个消息,无论消息是否必须作为多部分发送。这就是为什么您的 Observer 通常只为每条完整的消息触发一次,无论消息有多大。
自 KitKat 起,系统将自动保存任何非默认应用程序的传出消息,而对于多部分消息,每个部分将单独保存,每次都会触发你的观察者。当然,这对 KitKat 之前的任何事情都没有帮助,或者如果默认应用程序在更高版本中保存自己的消息。
一种可能是在您的 ContentObserver
中获取消息正文,并确定它会被拆分成多少个消息部分。 SmsMessage.calculateLength()
方法可以为我们做这件事。它返回一个 int
数组,其中的第一个元素将包含给定文本的消息计数。
例如,使用旧的onChange(boolean)
方法,支持API <16:
private class SmsObserver extends ContentObserver {
private static final Uri SMS_SENT_URI = Uri.parse("content://sms/sent");
private static final String COLUMN_ID = "_id";
private static final String COLUMN_BODY = "body";
private static final String[] PROJECTION = {COLUMN_ID, COLUMN_BODY};
// You might want to persist this value to storage, rather than
// keeping a field, in case the Observer is killed and recreated.
private int lastId;
public SmsObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
Cursor c = null;
try {
// Get the most recent sent message.
c = getContentResolver().query(SMS_SENT_URI, PROJECTION, null,
null, "date DESC LIMIT 1");
if (c != null && c.moveToFirst()) {
// Check that we've not already counted this one.
final int id = c.getInt(c.getColumnIndex(COLUMN_ID));
if (id == lastId) {
return;
}
lastId = id;
// Get the message body, and have the SmsMessage
// class calculate how many parts it would need.
final String body = c.getString(c.getColumnIndex(COLUMN_BODY));
final int numParts = SmsMessage.calculateLength(body, false)[0];
// Add the number of parts to the count,
// however you might be doing that.
addToCount(numParts);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (c != null) {
c.close();
}
}
}
}
如果您支持 API 16 及更高版本,我们可以使用 onChange(boolean, Uri)
重载,事情会变得简单一些,因为我们不一定需要跟踪最后一条消息 ID。
@Override
public void onChange(boolean selfChange, Uri uri) {
Cursor c = null;
try {
// type=2 restricts the query to the sent box, so this just
// won't return any records if the Uri isn't for a sent message.
c = getContentResolver().query(uri, PROJECTION, "type=2", null, null);
if (c != null && c.moveToFirst()) {
final String body = c.getString(c.getColumnIndex(COLUMN_BODY));
final int numParts = SmsMessage.calculateLength(body, false)[0];
addToCount(numParts);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (c != null) {
c.close();
}
}
}
关于android - 检测由于内容长度而发送的多条短信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41221109/