【问题标题】:How to update sms thread after inserting a draft in "content://sms/draft"在“content://sms/draft”中插入草稿后如何更新短信线程
【发布时间】:2019-08-26 18:38:36
【问题描述】:

我正在使用以下代码将草稿插入到 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,否则为该线程的id。

当我运行这段代码时,草稿确实被保存了,但是本机短信客户端(股票 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;
    }

如您所见,在我通过上面代码制作的草稿旁边没有“草稿”标签。

【问题讨论】:

  • 在消息应用中,打开草稿并再次关闭。查看草稿标签是否出现。这是因为需要运行某些 SQLite 触发器才能自动完成您未提供的值。
  • 正如我在问题中所写,草稿标签 确实 在我打开关闭线程后出现。有什么方法可以通过我的应用触发该触发器?
  • 如果您杀死消息应用程序并重新启动它,它会正确显示所有内容。这是消息传递应用程序的问题。所以,我不确定对此能做些什么。

标签: android sms android-contentresolver


【解决方案1】:

我已经有一段时间没有提出这个问题了,但这里是答案:

首先,如前所述,“草稿”提示未出现在 Native SMS 应用程序上这一事实不应该打扰任何人。对此无能为力,这只是 Native SMS 应用程序的工作方式。特别是在应用程序启动时初始化缓存,保存包含草稿的线程的线程 ID。草稿缓存仅从应用程序本身更新,而不是从 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 数据库根本没有记录,但您可以从 AOSP 获取 Telephony 类,看看如何添加/删除消息以及处理有关 sms 和 mms 的各种任务。 http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/android/provider/Telephony.java

【讨论】:

  • 这是否会更新草稿(如果有)?如果不是如何获取以前的草稿并更新
【解决方案2】:

我认为您的方法与内置消息传递应用程序不同。

如果与上述地址没有任何对话,则thread_id为0,否则为该线程的id。

据我所知,甚至草稿都是自动生成的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 访问消息数据,所以我不建议你使用。但现在是唯一的办法。

【讨论】:

  • 感谢您提出这个问题,因为它让我查找了有关 api 隐藏部分的一些信息。 Afaik 如果你写 thread_id = 0,它将生成一个唯一的 thread_id,至少在我的代码中是这样。我用屏幕截图和更新的代码稍微更新了我的问题。还没有新的结果。
  • 实际 thread_Id 是一个自动增量整数,因此它并不总是 0。此外,当您使用收件人地址作为参数查询 content://mms-sms/ThreadId 时,要么是已经存在的 thread_Id(如果地址组合匹配 recipient_Ids)或返回一个新的 thread_Id。为什么需要这样做,因为在 sms 表中,address 字段对于草稿为空。
【解决方案3】:

使用this answer中描述的方法,只需插入content://sms/draft而不是content://sms/sent

【讨论】:

  • 我尝试根据该答案更新我的代码,但结果保持不变:/ 请检查编辑
【解决方案4】:

非常感谢我尝试了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;
 }

}

【讨论】:

    猜你喜欢
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    相关资源
    最近更新 更多