I wanted to update the "message_count" column and "snippet" column of a sms conversation thread, using this content:"content://mms-sms/conversations". Because the snippet and message count is not updated when an SMS is deleted from the conversation thread.
But I got this error message: "MmsSmsProvider does not support deletes, inserts, or updates for this URI"
Below is my code:
ContentValues values = new ContentValues();
values.put("message_count", ent.getValue().getCount());
values.put("snippet", ent.getValue().getSnip());
Uri conUri = Uri.parse("content://mms-sms/conversations");
getContentResolver().update(conUri, values, null, null);
I also try like this:
Uri conUri = Uri.parse("content://mms-sms/conversations" + "/" + threadid);
getContentResolver().update(conUri, values, null, null);
But what I got is another error message:no such column: message_count: , while compiling: UPDATE pdu SET message_count=?,snippet=? WHERE thread_id=334
Thanks for any help
There is no way to update the count, snippet etc of a thread directly. But I can help you with your actual problem. There is actually a bug in the android code, which is the root of your issue. When you try to delete in the following way -
getContentResolver().delete("content://sms/", "_id=?", new String[] {id});
Android does not update the thread associated with that sms.
The solution is is to do this
getContentResolver().delete("content://sms/" + id, null, null);
For those who are curious what the bug is -
Android code does something stupid like this, when you delete using method 1 -
Delete all messages given by the query.
Get all the conversation threads associated with the messages given by the query and update them. Whoa wat ?! Step 1 just deleted messages given by query so, step 2 is always going to return a null set for threads associated with those message, as all the messages are already deleted.
Hope this helps.
Related
I am trying to maintain a contact database and get a callback for Add/Update/Delete as soon as something changes in the URI.
I have written a ContentObserver to observe on ContactsContract.Contacts.CONTENT_URI on contacts. I get a callback as soon as a contact changes and then I update my database by checking ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP.
While this works fine for add/update, it does does not work for deleting a contact.
I do not want to parse all the contacts that I have in memory and check against android database. That would take time and CPU.
I know there exists many question of these types but I am not able to figure out things specific to deleting the contact.
Does there exist a way to perform this ?
As I have posted in above comment as well, following code works for API level 18 and above.
You can query on a uri ContactsContract.DeletedContacts.CONTENT_URI to get the list of all the contacts that have been deleted.
My query looks like following :
String selection = ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP + " > ?";
String[] selectionArgs = new String[]{String.valueOf(mLastContactDeleteTime)};
Cursor cursor = mContext.getContentResolver().query(ContactsContract.DeletedContacts.CONTENT_URI, null, selection, selectionArgs, null);
I would like to modify contact's name in an Android device (GT N5110) with Android 4.4. I have tried to do that by this approach:
ContentValues contentValues = new ContentValues();
String selection = ContactsContract.Contacts._ID + " = ? " ;
String[] selectionArgs = new String[] { Integer.toString(id) };
contentValues.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, lastName);
contentValues.put(ContactsContract.Contacts.STARRED, 2); // *
contentValues.put(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, lastName);
contentValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, firstName);
return this.context.getContentResolver().update(ContactsContract.Contacts.CONTENT_URI,
contentValues, selection, selectionArgs);
The line marked with * was the only one which modified the contact database. I also tried by applyBatch and added the MIMETYPE selection (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE). The MIMETYPE approach throws some Exception with these message:
android.database.sqlite.SQLiteException: no such column: mimetype (code 1): , while compiling: SELECT _id FROM view_contacts_restricted WHERE _id = ? AND mimetype=?
I researched and tried suggestions present in update contacts display_name and Modifying contact information.
Can someone help me?
The following website explains it to you. It is a full tutorial by android itself. I highly recommend you use this website to first check if there is an answer to your query first before coming here.
http://developer.android.com/reference/android/provider/ContactsContract.Intents.html#EXTRA_FORCE_CREATE
What this website explains to you is
Send data to the contact you require to edit and it automatically opens the contact edit screen with the details which you passed to it.
If you want to know what all extras you can send to it. Visit the following link.
https://developer.android.com/reference/android/provider/ContactsContract.Intents.Insert.html
I am not sure if this is correct but it may be because of some security policy or so that you can't skip ui confirmation. But again I am not familiar with this so I may be wrong. I have not tested if this works or anything but I think it might help. Especially the second one:
http://developer.android.com/reference/android/provider/ContactsContract.Intents.html#EXTRA_FORCE_CREATE
And
http://www.techjini.com/blog/2011/10/31/insert-and-modify-contact-in-android/
I have tried to use the undocumented content provider (content://sms) to insert a SMS into the inbox, and the insertion is successful. Then I check the newly inserted mesage in the Messaging apps, however the time displayed is always the real time that the insertion is done, instead of the time I specified in ContentValues. After I clicked and viewed the message thread, the time is then updated to the value I set in ContentValues. Have I missed something? Please help, thanks so much
Her is part of my code
Uri uri = Uri.parse("content://sms");
ContentValues cv = new ContentValues();
cv.put("address", "99912345");
cv.put("date", 1309632433677);
cv.put("read", 1);
cv.put("type", 1);
cv.put("subject", null);
cv.put("body", "Testing message");
getContentResolver().insert(uri, cv);
The problem is that this is an undocumented, unofficial API, so in theory, you maybe shouldn't be using it. In practice, if you want to use it, you have to be prepared for Google to break your software in the J or some later release.
All that said, it turns out that there's a workaround. When you insert a message, that sets the thread's datestamp to the time of insert. But when you delete a message from a thread (identified by the "address" field in the "content://sms" provider), it has to recalculate the thread datestamp. So for every thread you stuff something into, stuff another dummy message in as well and then delete it. Which is easy because the insert method returns a Uri that you can call the delete method on. I suspect this is horribly inefficient.
Exactly this one worked for me:
getContentResolver().delete(Uri.parse("content://sms/conversations/-1"), null, null);
Even faster, just delete the -1th conversation (which doesn't exist) from sms/conversations uri to trigger the trigger.
contentResolver.delete(Uri.parse('content://sms/conversations/-1'), null, null);
On many phones this cannot be avoided as the messaging application is displaying the date time from the threads table which date time is build from an insert trigger. Some phones will allow you to update the threads provider but this will not work on all platforms.
I am trying to get call log by using the CallLog.Calls content provider. However, I am little lost about the query I need to make. I am able to make a query and load the result in a ListView. But the query return all types of call.
Of course I can use a switch-case and take appropriate action as per the types of call returned. But for my program I only need the outgoing call logs.
So, how do I modify the query to get only outgoing call types. (I believe I have to use CallLog.Calls.OUTGOING_TYPE somewhere?). I have tried to modify the query in various ways but I keep getting error. If I try to supply the CallLog.Calls.OUTGOING_TYPE as an selection arg I get an error as its an int type and the query looks for String type.
I may be missing something simple, but can't figure it out. Any help would be much appreciated. Thank You. Here's my query below,
getContentResolver().query(CallLog.Calls.CONTENT_URI,null, null, null, ORDER_BY );
Try this code snippet:
Cursor c = getContentResolver().query(CallLog.Calls.CONTENT_URI, null,
CallLog.Calls.TYPE + "=?",
new String[] { String.valueOf(CallLog.Calls.OUTGOING_TYPE) },
ORDER_BY);
in my app i want to delete the sms's/calls of specific numbers i am new to android can any body help me
For calls: use content provider described here: http://d.android.com/reference/android/provider/CallLog.Calls.html
I'm not sure about SMS.
I use this to delete a particular message from the SMS inbox:
//Delete entire SMS thread.
getContext().getContentResolver().delete(
Uri.parse("content://sms/conversations/" + threadID),
null,
null);
//Delete single message.
getContext().getContentResolver().delete(
Uri.parse("content://sms/" + messageID),
null,
null);
These work for me given a valid Thread ID or Message ID.