Android - Query All MMS & SMS from Specific Thread_ID - android

How can I query all messages sent by a specific address?
I couldn't find my answer on StackOverflow after many days of searching.
I'm currently getting all messages like this:
Uri uri = Uri.parse("content://sms/");
Cursor managedCursor = getContentResolver().query(uri, null, ("thread_id = " + ThreadID), null, "date ASC");
But this only returns SMS messages (no MMS). I tried changing content://sms/ to content://mms-sms/ but that was unrecognized. I also tried to query content://mms-sms/conversations/xxx where xxx is the thread_id but that just gave me a NullPointerException.
I've been searching for a solution to this for days. Other SMS apps such as Go SMS and Sliding Messaging can do it perfectly but I just can't seem to figure it out...

A null projection argument to content://mms-sms/conversations/xxx is what's causing the NullPointerException --- if you explicitly project the columns you want (e.g, {"address", "body", "date"}), it should work just fine.
However, querying by thread_id isn't strictly selecting based on the address the message is sent from; if you want that, you should probably look in content://sms/inbox (which ignores messages you've sent) and use selection arguments to query for the address you're interested in:
Uri uri = Uri.parse("content://sms/inbox");
Cursor managedCursor = getContentResolver().query(uri, null, "address=?", {targetedAddress}, "date ASC");

Related

How to retrieve all the phone numbers with just one query

Is it possible to retrieve all the phone numbers with just one query(it's ok even if it's a bit slow)?
I found many topics that suggest to make query for the contact list and then a query for each contact but that's really slow.
The only solutions that I found with one query, retrieve just the main number. I need all the numbers of each contact plus the type.
Thanks.
try this
Cursor cursor = getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[] {Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER}, null, null, Phone.DISPLAY_NAME + " ASC");

Looking for a common Contact ID between Telephony.Sms and CallLog.Calls

Goal: I'm trying to group SMS and calls from same (known) contacts.
I read SMS using Telephony.Sms.Inbox.CONTENT_URI and Telephone.Sms.Sent.CONTENT_URI.
I read calls using CallLog.Calls.CONTENT_UTI.
I get the contact's ID by following android is CallLog.Calls._ID the same with the contact id?: using Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, phoneNumber).
Now, having this PhoneLookup._ID, I want to list SMS from that contact.
Sadly Telephony.Sms.PERSON does not seem to store the same contact ID.
Question: How could I list SMS from that PhoneLookup._ID or if not possible, how could I achieve what I want: list SMS and calls from the same contact.
PS: Telephony.TextBasedSmsColumns.PERSON seems to refer the the deprecated Contacts.People API...
Telephony.Sms.PERSON actually matchs ContactsContract.DataColumns.RAW_CONTACT_ID.
So I used:
final Cursor cursor = getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
projection, selection, null, null);
Reading ContactsContract.DataColumns.RAW_CONTACT_ID.
https://developer.android.com/reference/android/provider/ContactsContract.DataColumns.html#RAW_CONTACT_ID

Android people app - what selection used to query contacts

I'm using the following cursor
Cursor c = context.getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI,
CONTACTS_PROJECTION,
ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1",
null, ContactsContract.Contacts.DISPLAY_NAME);
This works for retrieving a list of contacts but obviously only where they have a phone number. If I try removing the HAS PHONE NUMBER selection then the list that I get back is huge with 1000's and 1000's of contacts. I'm looking to get back the same list of contacts from my cursor that the "people" app does but I can't work out what selection they are using. Does anyone know?
ok, to answer my own question after doing some digging. instead of the phone number section this seems to work:
Cursor c = context.getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI,
CONTACTS_PROJECTION,
ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1",
null, ContactsContract.Contacts.DISPLAY_NAME);

How to use Data.HAS_PHONE_NUMBER

I am a little bit confuse about the how to use Data.HAS_PHONE_NUMBER.
I have inserted contacts along with some additional Data and I would like to retrieve some of those contacts.
If I'm running the following code eveything is fine:
Uri uri = Data.CONTENT_URI;
String[] projection = new String[]{Data.CONTACT_ID, Data.DISPLAY_NAME };
String selection = Data.DATA4+" = ?";
String[] selectionArgs = new String[] {MY_VALUE};
Cursor truContactCursor = mContext.getContentResolver().query(uri, projection, selection, selectionArgs, null);
Now, I would like to know if those contacts have a phone number so I added HAS_PHONE_NUMBER into the projection like this:
String[] projection = new String[]{Data.CONTACT_ID, Data.DISPLAY_NAME, Data.HAS_PHONE_NUMBER };
When running the query I got the following execption:
java.lang.IllegalArgumentException: Invalid column has_phone_number
Why can I not access to HAS_PHONE_NUMBER? There is no problem with Data.DISPLAY_NAME which is in the same table. How are we suppose to use Data.HAS_PHONE_NUMBER then?
Thanks for your answer
Use HAS_PHONE_NUMBER is used for checking whether an contact has at least one phone number.example:
ContentResolver cr = getContentResolver();  
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if(cursor.getCount()>0){
while (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));id
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if(cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))>0){
//Query phone here.
}
or add in projection:
String [] projection = {ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER};
Add "Data.MIMETYPE=ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE" to the selection statement.
The result cursor will include only the rows which have a phone number.
Tip.
There is the case: several numbers in one contact.
If you want all the numbers to be queried, add "ContactsContract.Data.DATA1" (Which means phone number) to the projection statement.
I encountered this same problem, and the only other reference to the problem I have found is another stackoverflow question.
I am planning on writing my own ContentProvider to do the "join" through programmatic means. That is, do the original query against the Data.CONTENT_URI but without the Data.HAS_PHONE_NUMBER projection, and then requery the given contact for the actual value of Data.HAS_PHONE_NUMBER. This surely lacks the performance of an actual DB join (being an n+1-type of select), but will provide the desired/expected functionality. This extra processing could be made conditional upon the OS level in order to maintain the efficiency on correctly functioning OS versions.
Given yulistic's answer above and my own experience, it would appear to be a bug in some versions of Android that this implicit join is not done. My Android v2.3.7 phone crashes with the same error you receive when Data.HAS_PHONE_NUMBER is in the projection, whereas my Android v4.2.2 tablet does not crash.
I have entered an Android Bug against the issue:
https://code.google.com/p/android/issues/detail?id=54095
Rob

Getting all contacts timestamp wise

I have been trying to get all contacts of device sorted by the order they were added.
I am using following query:
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.CONTACT_STATUS_TIMESTAMP };
Cursor c = getContentResolver().query(uri, projection, null, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_STATUS_TIMESTAMP);
It is not making any difference whether I am passing null or ContactsContract.CommonDataKinds.Phone.CONTACT_STATUS_TIMESTAMP in the sort order of the query
After inspection, the cursor has null in all timestamp columns. Is there a way to get this done or what I am doing wrong in this?
That is the timestamp for the status update for the contact. You are getting null probably because none of the contacts have status updates.
Because of how contacts are aggregated, i don't think there is a way to find out which contact was added first because a contact's ID can actually change and appear to be added later than it originally was. Why do you want to figure this information out?

Categories

Resources