【问题标题】:Android SMS inbox unread count issuesAndroid SMS收件箱未读计数问题
【发布时间】:2012-12-08 12:25:04
【问题描述】:

我创建了一个小 Android 应用程序,它对传入的 SMS 消息做出反应。问题是我似乎无法可靠地获取收件箱中未读邮件的数量。

这里有一个最低限度的类来说明这个问题。有时它会打印“收到短信!未读计数:0”,有时会打印“收到短信!未读计数:1”。对我来说,如果每当程序流输入该命令时,未读计数总是至少为 1,这将显得更合乎逻辑。我一直在通过从一个模拟器向另一个模拟器发送 SMS 消息来测试这一点(您可以通过将消息发送到模拟器号码来做到这一点——比如 5554)。

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

public class SmsReceiver extends BroadcastReceiver {
private static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";

@Override
public void onReceive(Context context, Intent intent) {
    Log.d("onReceive", "Got something: "+intent.getAction());
    if (!SMS_RECEIVED_ACTION.equals(intent.getAction())) {
        Log.d("onReceive", "Returning.");
        return;
    }
    Log.d("onReceive", "Got SMS! Unread count: " + getNumberOfUnreadMessages(context));
    // Do stuff
}

public int getNumberOfUnreadMessages(Context context) {
    final Uri SMS_INBOX_URI = Uri.parse("content://sms/inbox");
    Cursor inboxCursor = context.getContentResolver().query(SMS_INBOX_URI, null, "read = 0", null, null);
    int unreadMessagesCount = inboxCursor.getCount();
    inboxCursor.close();
    return unreadMessagesCount;
}
}

最后,这是 AndroidManifest.xml 文件中的相关部分:

<receiver android:name=".SmsReceiver" >
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

如何获得正确数量的未读消息?

编辑/添加: 或者,如果是在保存 SMS 之前发送广播的情况,有没有办法订阅应用程序以侦听新 SMS 消息的事件保存到收件箱?

【问题讨论】:

  • 广播接收器也有同样的问题。似乎当广播从游标检查未读计数时,新消息丢失了,就像在消息存入数据库之前触发广播一样,所以它给出了错误计数。我只是喜欢 inboxCursor.getCount() + 1;
  • @Samet 是的,看起来就是这样。那你做了什么?如何仅在将消息保存到数据库后才触发广播?请注意,它不会经常失败,只是每隔一段时间左右,所以getCount() + 1 不是一个好的解决方案。
  • 但是你应该避免 getCount() 非常慢,我有经验,再有一些消息,应用程序会挂起。您应该只创建一个 int count = 1;在循环之外,在光标中移动时,执行 count ++;这样它需要毫秒而不是秒,我想你会得到真正的计数。
  • 我从未尝试过搜索为什么会发生这种情况,我不确定,但您可以更改广播的优先级,使其最后触发。我认为这个问题是由于默认的短信应用程序,在你的广播之后在数据库中插入新的短信,就像你没有在数据库中插入任何东西,只是检索了短信未读计数。

标签: android sms


【解决方案1】:

如果您想观察短信收件箱,请使用这样的 ContentObserver:

OnCreate() :

contentObserver observer = new contentObserver(handler);
getContentResolver().registerContentObserver(Uri.parse("content://sms/inbox"), true, observer);

创建一个新的内部类或外部类:

public class contentObserver extends ContentObserver {

    public contentObserver(Handler handler) {
        super(handler);
        // you can use a handler if you want or directly do everythinh onChange();
    }

    @Override
    public void onChange(boolean selfChange) {
        // Do your stuff here
        super.onChange(selfChange);
    }
} 

OnDestroy():

getContentResolver().unregisterContentObserver(observer);

【讨论】:

  • 谢谢,这可能比我目前的方法更好。一旦我有机会尝试这个,我会决定接受这个答案。
【解决方案2】:

我遇到了同样的问题。当您实际收到短信时,似乎会触发 BroadcastReceiver。这可以在 SmsManager 将消息写入数据库之前。

在收到广播后等待几秒钟,或者手动记录收到广播的次数并增加计数,保存到私有 SharedPreferences 并在用户阅读消息时减少计数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-18
    • 2011-09-16
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多