2012-12-08 33 views
1

我已經創建了一個小的Android應用程序,可以響應傳入的短信。問題是,我似乎無法可靠地獲取收件箱中未讀郵件的數量。Android短信收件箱未讀計數問題

下面是一個最低限度的課程來說明問題。有時它會打印「Got SMS!Unread count:0」,有時會打印「Got SMS!Unread count: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消息被保存到收件箱中?

+0

我有與廣播接收機相同的問題。看來,當廣播檢查遊標的未讀計數時,新消息就會丟失,就像在數據庫中存儲消息之前觸發廣播一樣,所以會導致錯誤的計數。我只是喜歡inboxCursor.getCount()+ 1; – Samet

+0

@Samet是的,就是這樣。那麼你對此做了什麼?只有在郵件保存到數據庫後,如何製作廣播觸發器?請注意,它不會經常失敗,只是在其他時間左右,所以'getCount()+ 1'不是一個好的解決方案。 – ZeroOne

+0

,但你應該避免getCount()這很慢,我有經驗,有更多的消息,應用程序將掛起。你應該創建一個int count = 1;在循環外,並在遊標中移動時,執行count ++;這樣它需要幾毫秒而不是幾秒鐘,我想你會得到真正的計數。 – Samet

回答

4

如果你想觀察的短信收件箱,使用這樣的ContentObserver:)

的OnCreate(:

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

創建一個新的內部類或outter類:

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); 
+0

謝謝,這可能是比我現在更好的方法。一旦我有機會嘗試這個,我會決定接受這個答案。 – ZeroOne

0

我有同樣的問題。看起來,當您實際收到短信時,BroadcastReceiver會被觸發。這可以在SmsManager將消息寫入數據庫之前。

收到廣播後等待幾秒鐘,或手動記錄您接收廣播的次數並增加計數,保存到私有SharedPreferences並在用戶讀取消息時減少計數。