How to get notify which SMS got read from native(phone) if multiple unread SMS are present in phone(

If 3 unread SMS messages are present in native(phone), and user has read one of the SMS. How to identify which SMS got read(from native) in our application.

Currently I am using ContentObserver and onChange() method is called when user read SMS from native(phone).

I am able to get all unread SMS messages:

Cursor cursor = this.getContentResolver().query(Uri.parse("content://sms/"), null, "read = 0", null, null);

How to identify which SMS got read from native(phone). Any help or guidance will be well appreciated.

In Nexus 4(Android 4.3) - API 18), If notification(in device status bar) for two unread SMS(belongs two different sender) in Android Native Sms Client, user clicks on that notification, onChange(context, uri) is called in my aaplication, inside it I have tried to get id of the read SMS:

String id = uri.getLastPathSegment();

For above mentioned case, "inbox" as value of "id" came. But for reading any of the SMS by user from in Android Native Sms Client, onChange(context, uri) method is not invoked.

In Samsung Galaxy S3(Android 4.1.2 - API 16), onChange(context, uri) is not at all invoked in either of the case (i.e. if user read the SMS from Native or user clicks on the notification(in device status bar) for two unread SMS(belongs two different sender) in Android Native Sms Client.

(In API 16, when new SMS received in native, onChange(context, uri) is called and value of "id" is equal to the unique ID for that SMS - Tested on Nexus 4(Android 4.3))

Note: Here, "from native" means "from the device's default SMS client".


To determine definitely which message has changed from unread to read, you will likely have to track the state of all unread messages in your own data structure and compare during each onChange detected by your Content Observer to determine which/if any messages changed read states. You may able to improve performance by including additional projection and selection arguments in the Content Resolver queries to narrow the data set to only the fields of interest.

Hopefully, the upcoming changes to the SMS APIs that Google is promising in Android 4.4 will make the use of hidden APIs and Content Providers unnecessary for these sorts of purposes moving forward.

You may also be able to determine the SMS that was read (or at least the thread) by looking for the markAsRead debug message that is generated by the com.android.mms.data.Conversation class used by the native Messaging app:

D/Mms (1645): [192] markAsRead: update read/seen for thread uri: content://mms-sms/conversations/4

However, that may not always be reliable and would not work on Android 4.1+ devices unless your app has system privileges due to the restrictions placed on the READ_LOGS permission in API Level 16.


  • freegeoip doesn't work anymore
  • enumerating all possible strings of length K from an alphabet in Python [duplicate]
  • Fast vectorized conversion from RGB to BGRA
  • RecyclerView scrolling top when loading new data
  • set and get value using Session storage for html drop down with jquery
  • Referencing dictionaries in Python
  • Dynamically derive a class in python [duplicate]
  • Create new column from specific rows in pandas dataframe
  • Left factoring grammar
  • How to find and replace, skipping lines containing a particular character?
  • Atmel SAM3X dual bank switching not working
  • Why is this regex failing when adding anchors?
  • jquery ui datepicker error on beforeShowDay
  • Create child Window of another process's HWND? (e.g. screensaver preview)
  • LatLong falls within a given polygon in D3 + Leaflet
  • Why does this empty dict break shared references?
  • opengl window freezing during move/resize
  • Entity Framework ObjectContext: Concurrency
  • Ruby and class variables in inherit class
  • Using MouseListener to select a range of cells in a grid
  • Dart - Isolate Cross Window Communication
  • Fail:(TESTMODE) Transactions of this market type cannot be processed on this system
  • Elasticsearch script query involving root and nested values
  • Why use database factory in asp.net mvc?
  • Android Google Maps API v2 start navigation
  • How do I configure context broker accept post requests from my remote sensor?
  • System.InvalidCastException: Specified cast is not valid
  • Custom Tabgroup Appcelerator
  • iOS: Detect app start via notification press
  • Dialing with Intent.ACTION_CALL stopps at # in phone number
  • Initializer list vs. initialization method
  • Javascript Callbacks with Object constructor
  • SetUp method failed while running tests from teamcity
  • How to delete a row from a dynamic generate table using jquery?
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • json Serialization in asp
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • How to stop GridView from loading again when I press back button?
  • apache spark aggregate function using min value
  • Sorting a 2D array using the second column C++