32

用于发送短信的代码在 Android 4.3 (Jelly Bean) 之前运行良好,但自 4.4 (KitKat) 起停止工作

我只是为用户准备短信,但他们需要选择要发送到的号码。

我使用的代码是:

Intent sendIntent = new Intent(Intent.ACTION_VIEW);         
    sendIntent.setData(Uri.parse("sms:"));
    sendIntent.putExtra("sms_body", smsText);

    activity.startActivity(sendIntent);

由于它停止工作,我也尝试了ACTION_SEND并且ACTION_SENDTO都没有工作,我也尝试了sendIntent.setType("vnd.android-dir/mms-sms");,但再次没有任何效果。

我查看了 Stack Overflow answer 1answer 2上的几个答案,但两个答案都没有满足我的要求。

我想做的事:

  • 仅使用短信应用发送短信,而不是通过所有服务于发送意图的应用
  • 为用户准备文本
  • 让用户选择要发送消息的电话号码

对于版主:这不是重复的问题,因为问题并没有问完全相同的东西,这里需要发送没有电话号码的短信,并且没有任何问题和答案处理。

4

4 回答 4

80

我附上了通过执行以下操作解决问题的代码:

  • 检查操作系统版本
  • 如果是旧版本(在 KitKat 之前),请使用旧方法
  • 如果是新 API,请检查默认的 sms 包。如果有,则设置为包,否则,让用户选择共享应用程序。

这是代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) //At least KitKat
    {
        String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(activity); //Need to change the build to API 19

        Intent sendIntent = new Intent(Intent.ACTION_SEND);
        sendIntent.setType("text/plain");
        sendIntent.putExtra(Intent.EXTRA_TEXT, smsText);

        if (defaultSmsPackageName != null)//Can be null in case that there is no default, then the user would be able to choose any app that support this intent.
        {
            sendIntent.setPackage(defaultSmsPackageName);
        }
        activity.startActivity(sendIntent);

    }
    else //For early versions, do what worked for you before.
    {
        Intent sendIntent = new Intent(Intent.ACTION_VIEW);
        sendIntent.setData(Uri.parse("sms:"));
        sendIntent.putExtra("sms_body", smsText);
        activity.startActivity(sendIntent);
    }
于 2013-11-19T18:19:18.000 回答
19

这个应该适用于所有 android 版本和所有短信应用程序(包括环聊)。

public static boolean sendSms(Context context, String text, String number) {
    return sendSms(context, text, Collections.singletonList(number));
}

public static boolean sendSms(Context context, String text, List<String> numbers) {

    String numbersStr = TextUtils.join(",", numbers);

    Uri uri = Uri.parse("sms:" + numbersStr);

    Intent intent = new Intent();
    intent.setData(uri);
    intent.putExtra(Intent.EXTRA_TEXT, text);
    intent.putExtra("sms_body", text);
    intent.putExtra("address", numbersStr);

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        intent.setAction(Intent.ACTION_SENDTO);
        String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(context);
        if(defaultSmsPackageName != null) {
            intent.setPackage(defaultSmsPackageName);
        }
    } else {
        intent.setAction(Intent.ACTION_VIEW);
        intent.setType("vnd.android-dir/mms-sms");
    }

    try {
        context.startActivity(intent);
    } catch (ActivityNotFoundException e) {
        e.printStackTrace();
        return false;
    }

    return true;
}
于 2015-04-27T16:37:21.727 回答
17

结合所提出的解决方案,以下提供预设接收者文本。

Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) // Android 4.4 and up
{
    String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(activity);

    intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:" + Uri.encode(toContact.toString())));
    intent.putExtra("sms_body", text);

    if (defaultSmsPackageName != null) // Can be null in case that there is no default, then the user would be able to choose any app that supports this intent.
    {
        intent.setPackage(defaultSmsPackageName);
    }
}
else
{
    intent = new Intent(Intent.ACTION_VIEW);
    intent.setType("vnd.android-dir/mms-sms");
    intent.putExtra("address", toContact.toString());
    intent.putExtra("sms_body", text);
}
activity.startActivity(intent);

剩下的唯一问题是您最终进入了环聊(Nexus 5),您可能必须多次按“返回”才能有效取消短信。

于 2014-01-06T15:14:29.307 回答
0

在 Kotlin 中,以下代码有效:

val defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(activity)  
            val sendIntent = Intent(Intent.ACTION_SEND)
            sendIntent.type = "text/plain"
            sendIntent.putExtra("address", "sms:"+contactNumber)
            sendIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.share_msg_body))
            Timber.e("defaultSmsPackageName: "+defaultSmsPackageName)
            if (defaultSmsPackageName != null){ //Can be null in case that there is no default, then the user would be able to choose any app that support this intent.
                sendIntent.setPackage(defaultSmsPackageName)
                activity!!.startActivity(sendIntent)
            }
于 2020-06-25T12:14:42.530 回答