Android KitKat 4.4 Hangouts cannot handle Sending SMS intent

Solution 1:

I attached a code that solve the problem by doing the following:

  • Check the OS version
  • In case that older version (prior to KitKat), use the old method
  • If new API, check the default sms package. if there is any, set it as the package, otherwise, let the user choose the sharing app.

Here is the code:

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

Solution 2:

This one should work on all android versions and all sms apps (including Hangouts).

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

Solution 3:

Combining the proposed solutions, the following provides presetting the recipient and the text.

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

The only problem remaining is that you end up in Hangouts (Nexus 5), and you might have to press "back" multiple times to effectively cancel the SMS.