如何在安卓手机上将短信保存到收件箱?

41

我编写了以下代码来发送短信消息。

SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(destAddr, null, mMessageText, il, null);

但是这并没有在我的收件箱中更新,我需要将同样的消息保存在收件箱中, 或者有没有办法调用本机短信应用程序发送短信?


8
“Programmatically” 的意思是“通过编程代码实现”。这是一个完全合法的词,在大多数最近几年出版的词典中都可以找到。有时需要区分那些不尝试通过编程代码实现某事的用户提出的偶尔问题。当然,这些问题应该在Super User上提出,而不是在这里。问题在于,有些任务不写一行代码就更简单、更常见。这个澄清词语能够阻止人们提供那些显而易见的答案。 - Cody Gray
5个回答

60
您可以使用短信内容提供程序来读取和写入短信消息:

您可以使用短信内容提供程序来读取和写入短信消息:

ContentValues values = new ContentValues();
values.put("address", "123456789");
values.put("body", "foo bar");
getContentResolver().insert(Uri.parse("content://sms/sent"), values);
我不知道你为什么想要编写一个你发送到收件箱的消息,但如果这是你想要的,只需将上述URI更改为"content://sms/inbox"即可。
或者,您可以通过使用以下类似的意图启动活动来交给消息应用程序处理:
Intent sendIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("sms://"));
sendIntent.putExtra("address", "123456789");
sendIntent.putExtra("sms_body", "foo bar");
startActivity(sendIntent);

编辑: 然而,sms:// 内容提供程序不是SDK的一部分,因此我强烈建议不要在公共应用程序中使用这样的代码,原因有几个


6
短信内容提供商不是Android SDK的一部分。您的代码将在将SMS客户端替换为自己的设备上中断。您的代码可能会在未来的Android版本中出现问题。 - CommonsWare
4
@CommonsWare:你知道这个问题是否有“官方”解决方案吗?处理未记录的API似乎确实很危险,但我迄今为止找不到其他解决方案。 - ereOn
很抱歉在一個這麼老的問題上發帖,但是除了使用sms://cp之外還有其他選擇嗎? 我正在尋找這個,但似乎這是唯一的方法。 - Epicblood
我已经实现了上述代码,它将消息存储到收件箱中。但是不知何故,我无法找到存储的短信。而且我甚至没有收到任何错误/异常。有人可以帮忙吗?先感谢了。 - satyapol

28

如果您想手动将某些短信放入收件箱并带有发件人姓名,则:

  ContentValues values = new ContentValues();
  values.put("address", "+923359110795");//sender name
  values.put("body", "this is my text");
  getContentResolver().insert(Uri.parse("content://sms/inbox"), values);

也将它们添加到清单中。

 <uses-permission android:name="android.permission.READ_SMS"/>
 <uses-permission android:name="android.permission.WRITE_SMS"/>

现在这段代码将添加一个带有定义的发件人名称的短信到收件箱,因此您可以使用此解决方案轻松处理您的问题。


READ_SMS 真的需要吗?我只期望需要 WRITE_SMS - Flow
@Flow 亲爱的,使用两者都可以,但有时会出现问题,如果您写入两个权限将更好,否则我认为可以不需要 READ_SMS 权限。 - Pir Fahim Shah
请将 my_values 编辑为 values 或反之。 - user1755546
1
需要使用READ_SMS,我也以为WRITE_SMS可以,但它崩溃了。 - sports
@sports 是的,你说得对,如果没有 WRITE_SMS 权限可能会导致出现错误。 - Pir Fahim Shah
显示剩余2条评论

8

这段代码适用于所有的Android版本,包括kitkat(19)以上的版本。

public boolean saveSms(String phoneNumber, String message, String readState, String time, String folderName) {
        boolean ret = false;
        try {
            ContentValues values = new ContentValues();
            values.put("address", phoneNumber);
            values.put("body", message);
            values.put("read", readState); //"0" for have not read sms and "1" for have read sms
            values.put("date", time);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                Uri uri = Telephony.Sms.Sent.CONTENT_URI;
                if(folderName.equals("inbox")){
                    uri = Telephony.Sms.Inbox.CONTENT_URI;
                }
                mActivity.getContentResolver().insert(uri, values);
            }
            else {
                mActivity.getContentResolver().insert(Uri.parse("content://sms/" + folderName), values);
            }

            ret = true;
        } catch (Exception ex) {
            ex.printStackTrace();
            ret = false;
        }
        return ret;
    }

如何调用

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        final String myPackageName = getPackageName();
        if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) {

            Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
            intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, myPackageName);
            startActivityForResult(intent, 1);
        }else {
            saveSms("111111", "mmmmssssggggg", "0", "", "inbox");
        }
    }else {
        saveSms("111111", "mmmmssssggggg", "0", "", "inbox");
    }

onActivityResult

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == 1) {
        if (resultCode == RESULT_OK) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                final String myPackageName = getPackageName();
                if (Telephony.Sms.getDefaultSmsPackage(mActivity).equals(myPackageName)) {

                    //Write to the default sms app
                    saveSms("111111", "mmmmssssggggg", "0", "", "inbox");
                }
            }
        }
    }
}

获取更多详细信息或示例应用,请访问以下链接: http://wisdomitsol.com/blog/android/sms/how-to-programmatically-save-sms-to-inbox-or-sent-in-android


你提供的链接中没有“更多信息”。它只是对这个未解释的答案的重复(本身似乎是其他早已发布的答案的副本)。而且,你又一次包含了一个未公开的链接到你自己的网站。我已经删除了这个链接。 - Andrew Barber

-1
ContentValues values = new ContentValues();
values.put("address", phoneNumber);
values.put("body", multimessage);
values.put("read", 1); //"0" for have not read sms and "1" for have read sms
Uri uri = Telephony.Sms.Sent.CONTENT_URI;
Activity ctx = this.cordova.getActivity();
ctx.getContentResolver().insert(uri, values);

-1
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.putExtra("sms_body", "Content of the SMS goes here...");
sendIntent.setType("vnd.android-dir/mms-sms");
startActivity(sendIntent);

调用本地短信应用程序并附带内容


使用 content://sms/ 有什么区别?我很感兴趣是因为我注意到创建未读短信不会触发任何本机通知。这种方式是否会触发某些通知? - sports

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接