Как обновить ветку смс после вставки черновика в content://sms/draft

Я использую следующий код, чтобы вставить черновик в 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 равен 0, если не было никакого разговора с указанным выше адресом, иначе это идентификатор этого потока.

Когда я запускаю этот код, черновик действительно сохраняется, но поток в собственном клиенте sms (стандартный Android 4.0.3) не обновляется как черновик [я вижу тело черновика сообщения, но на нем нет метки черновика. Я должен открыть-закрыть ветку, чтобы быть отмеченным]. Я где-то читал, что есть проблема с тем, что поток не обновляется должным образом. Как я могу принудительно обновить потоки, чтобы они отображались нормально на всех клиентах?

ИЗМЕНИТЬ:

Прочитав ваши ответы, я немного обновил свой код, но проблема осталась. Я добавил скриншот ниже, так как, когда я писал свой вопрос, я торопился и не мог написать его достаточно четко.

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;
    }

занятый кот

Как видите, рядом с черновиком, который я сделал с помощью приведенного выше кода, нет ярлыка «Черновик».


person Alex Styl    schedule 11.10.2012    source источник
comment
В приложении для обмена сообщениями откройте черновик и снова закройте его. Посмотрите, появляется ли черновая этикетка или нет. Это связано с тем, что определенные триггеры SQLite необходимы для автоматического завершения значений, которые вы не предоставили.   -  person S.D.    schedule 12.10.2012
comment
Как я писал в своем вопросе, метка черновика действительно появляется после того, как я открываю-закрываю ветку. Есть ли способ запустить этот триггер через мое приложение?   -  person Alex Styl    schedule 12.10.2012
comment
Если вы убьете приложение для обмена сообщениями и перезапустите его, оно покажет все правильно. Это проблема приложения для обмена сообщениями. Итак, я не уверен, что можно сделать по этому поводу.   -  person S.D.    schedule 12.10.2012


Ответы (4)


Прошло некоторое время с тех пор, как я задал этот вопрос, но вот ответ:

Прежде всего, как уже говорилось ранее, тот факт, что подсказка «Черновик» не отображается в приложении Native SMS, никого не должен беспокоить. С этим ничего нельзя поделать, и именно так работает приложение Native SMS. В частности, кеш инициализируется при запуске приложения, сохраняя идентификаторы потоков, содержащих черновик. Кэш черновиков обновляется только из самого приложения, а не из фактического изменения в таблице sms.

Для части сохранения черновика вот фрагмент кода для правильного сохранения черновика:

   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);
    }

Примечание. Черновики сообщений могут содержать или не содержать адрес получателя сообщения. Черновики сохраняются в цепочке (цепочка может содержать много получателей)

Хотя база данных sms вообще не документирована, вы можете взять класс Telephony из AOSP и посмотреть, как добавлять/удалять сообщения и выполнять различные задачи, связанные с sms и mms. http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/android/provider/Telephony.java

person Alex Styl    schedule 15.05.2013
comment
обновит ли это черновик, если таковой имеется? если нет, как получить предыдущий черновик и обновить - person Dr. aNdRO; 26.07.2018

Я думаю, что ваш подход отличается от встроенного приложения для обмена сообщениями.

thread_id равен 0, если не было никакого разговора с указанным выше адресом, иначе это идентификатор этого потока.

Насколько я знаю, даже черновик сгенерирован автоматически thread_id. Если это не так, все черновики (если адрес получателя никогда не появлялся) будут сгруппированы в одном диалоге с thread_id = 0.

Вот как встроенное приложение добавляет черновик.

 public static final Uri SmsCONTENT_URI =
            Uri.parse("content://sms");
     ContentValues values = new ContentValues(3);
        values.put("thread_id", threadId);
        values.put("body", contents); // 
        values.put("type", Sms.MESSAGE_TYPE_DRAFT); // type = 3 is draft.
        SqliteWrapper.insert(mActivity, mContentResolver, Sms.CONTENT_URI, values);

Последнее напоминание: это не public API для доступа к данным сообщения, поэтому я не предлагаю вам использовать. Но теперь это единственный путь.

person Trung Nguyen    schedule 11.10.2012
comment
Спасибо, что подняли этот вопрос, так как это заставило меня поискать информацию о скрытой части API. Afaik, если вы напишете thread_id = 0, он сгенерирует уникальный thread_id, по крайней мере, в моем коде. Я немного обновил свой вопрос со скриншотом и обновленным кодом. Пока нет нового результата. - person Alex Styl; 12.10.2012
comment
Фактический thread_Id является целым числом с автоматическим увеличением, поэтому он не всегда равен 0. Кроме того, когда вы запрашиваете content://mms-sms/ThreadId с адресами получателей в качестве параметров, возвращается либо уже существующий thread_Id (если комбинация адресов соответствует recipient_Ids), либо новый thread_Id. Зачем это нужно, т.к. в таблице смс поле address пусто для черновиков. - person S.D.; 12.10.2012

Используйте метод, описанный в этом ответе, просто вставьте content://sms/draft вместо content://sms/sent.

person S.D.    schedule 11.10.2012
comment
Я попытался обновить свой код в соответствии с этим ответом, но результат остается прежним:/ Проверьте редактирование, если хотите. - person Alex Styl; 12.10.2012

большое спасибо, я попробовал save_draft() попробовать это и вставить в inbox/sent/draft и т. д....

public class AddData {

Activity act;
Context ctx,context;
ContentResolver cr;

public AddData(Activity act)
{

    cr = act.getContentResolver();
    this.act = act;
}
public void addsms(String address,String body,String date,String type,String read)
{
    String[] addr = address.split(" ");
    String thread_id = save_draft(addr);
    ContentValues values = new ContentValues();
     values.put("body", body);
     values.put("date", date);
     values.put("type", type);
     if(type.equals("3"))
     {
         values.put("thread_id", thread_id); 
     }else
     {
         values.put("address", address);
     }

     Uri uri = cr.insert(Uri.parse("content://sms/"), values);
     cr.notifyChange(uri, null);

}

 protected String save_draft(String[] recipients) {
     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();
     String thread_id = get_thread_id(uri).toString();
     Log.d("thread_id", thread_id + " ");


     //^tried "content://sms/" as well, but got the same result
     return thread_id;
 }

 private Long get_thread_id(Uri uri) {
     long threadId = 0;
     Cursor cursor = act.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;
 }

}

person Piyush Machhoya    schedule 14.05.2013