Search code examples
androidsmsandroid-contentresolver

How to update sms thread after inserting a draft in "content://sms/draft"


I am using the following code to insert a draft into content://sms/draft

        ContentValues values = new ContentValues();
        values.put("address", receiver2);
        values.put("body", body2);
        values.put("date", String.valueOf(System.currentTimeMillis()));
        values.put("type", "3");
        values.put("thread_id", thread_id);
        getContentResolver().insert(Uri.parse("content://sms/draft"), values);

thread_id is 0 if there wasn't any conversation with the address above, else it's the id of that thread.

When I run this code, the draft is indeed saved, but thread in the native sms client (stock android 4.0.3) isn't updated as "draft" [I can see the draft message body, but there is no "Draft" label on it. I have to open-close the thread, in order to be marked as marked]. I have read somewhere that there is an issue with the thread not updating properly. How can I force the threads to be updated so it shows ok in all the clients?

EDIT:

Having read your answers, I have updated my code a bit, but the problem remains. I have added a screenshot below, since when I wrote my question I was in a hurry and couldn't write it clearly enough.

protected void save_draft(String[] recipients, String body) {
        Uri threadIdUri = Uri.parse("content://mms-sms/threadID");
        Uri.Builder builder = threadIdUri.buildUpon();
        for (String recipient : recipients) {
            builder.appendQueryParameter("recipient", recipient);
        }
        Uri uri = builder.build();
        Long thread_id = get_thread_id(uri);
        Log.d("thread_id", thread_id + " ");

        ContentValues values = new ContentValues();
        values.put("body", body);
        values.put("date", String.valueOf(System.currentTimeMillis()));
        values.put("type", 3);
        values.put("thread_id", thread_id);
        getContentResolver().insert(Uri.parse("content://sms/draft"), values);
        //^tried "content://sms/" as well, but got the same result
    }

    private Long get_thread_id(Uri uri) {
        long threadId = 0;
        Cursor cursor = getContentResolver().query(uri, new String[] { "_id" },
                null, null, null);
        if (cursor != null) {
            try {
                if (cursor.moveToFirst()) {
                    threadId = cursor.getLong(0);
                }
            } finally {
                cursor.close();
            }
        }
        return threadId;
    }

a busy cat

As you can see, there is no "Draft" label, next to the draft I made via the code above.


Solution

  • It's been a while since I made this question, but here is the answer:

    First of all as stated before, the fact that the "Draft" hint doesn't appear on the Native SMS app, shouldn't be bothering anyone. Nothing can be done about it, and it's just the way the Native SMS app works. In particular a cache is initialised when the app starts, saving the thread ids of the threads that contain a draft. The draft cache is updated only from the app itself and not from an actual change in the sms table

    For the saving draft part here is the piece of code to save a draft properly:

       public static final Uri CONTENT_URI =
                    Uri.parse("content://sms/draft");
    
       public static Uri addDraft(ContentResolver resolver,
                String address, String body, String subject,
                Long date,  long threadId) {
            ContentValues values = new ContentValues(6);
    
            values.put(ADDRESS, address);
            if (date != null) {
                values.put(DATE, date);
            }
            values.put(READ, Integer.valueOf(1));
            values.put(SUBJECT, subject);
            values.put(BODY, body);
            if (threadId != -1L) {
                values.put(THREAD_ID, threadId);
            }
            return resolver.insert(CONTENT_URI , values);
        }
    

    Note: Draft messages may or may not contain the address of the recipient of the message. Drafts are saved on the thread (a thread can contain many recipients)

    Although the sms database is not documented at all, you can grab the Telephony class from the AOSP and have a look at how to add/remove messages and handle various tasks about sms and mms. http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/android/provider/Telephony.java