3

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.

4

4 に答える 4

5

この質問をしてからしばらく経ちましたが、答えは次のとおりです。

まず、先に述べたように、「ドラフト」のヒントがネイティブ SMS アプリに表示されないという事実は、誰も気にする必要はありません。それについては何もできません。それがネイティブ 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

于 2013-05-15T22:37:41.607 に答える
3

あなたのアプローチは組み込みのメッセージング アプリケーションとは異なると思います。

上記のアドレスとの会話がなかった場合、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メッセージ データにアクセスするためのものではないため、使用することはお勧めしません。しかし、今は唯一の方法です。

于 2012-10-11T16:22:59.257 に答える
2

この回答で説明されている方法を使用してcontent://sms/draftくださいcontent://sms/sent

于 2012-10-11T13:41:59.210 に答える
2

どうもありがとう、私は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;
 }

}

于 2013-05-14T11:42:12.547 に答える