我该如何通过我的安卓应用向特定联系人发送WhatsApp消息?

6

我正在开发一款安卓应用程序,我需要从WhatsApp发送消息给特定联系人。 我尝试了以下代码:

Uri mUri = Uri.parse("smsto:+999999999");
Intent mIntent = new Intent(Intent.ACTION_SENDTO, mUri);
mIntent.setPackage("com.whatsapp");
mIntent.putExtra("sms_body", "The text goes here");
mIntent.putExtra("chat",true);
startActivity(mIntent);

问题在于 WhatsApp 并未接收到“sms_body”参数,尽管联系人已被选择。

1
请查看常见问题解答 - OneCricketeer
目前还不支持通过意图打开 WhatsApp 中的特定联系人。 - Swaminathan V
@Johny Moo 你能否向特定联系人发送消息? - chetan rane
14个回答

22

有一个方法。确保你提供的联系方式必须作为意图字符串传递,而不带前缀“+”。国家代码应该附加为电话号码的前缀。

例如:'+918547264285' 应当作为 '918547264285' 传递。这里的开头'91'是国家代码。

注意:将“YOUR_PHONE_NUMBER”替换为你想要发送消息的联系方式。

以下是代码片段:

 Intent sendIntent = new Intent("android.intent.action.MAIN");
 sendIntent.setComponent(new  ComponentName("com.whatsapp","com.whatsapp.Conversation"));
 sendIntent.putExtra("jid", PhoneNumberUtils.stripSeparators("YOUR_PHONE_NUMBER")+"@s.whatsapp.net");
 startActivity(sendIntent);

更新:

上述的黑客攻击不能用来添加任何特定的消息,因此这里有一个新的方法。在此处以国际格式传递用户手机号码,不带任何括号、破折号或加号。例如:如果用户来自印度,他的手机号码为94xxxxxxxx,那么国际格式将是9194xxxxxxxx。不要忘记将国家代码作为前缀附加到手机号码后面。

  private fun sendMsg(mobile: String, msg: String){
    try {
        val packageManager = requireContext().packageManager
        val i = Intent(Intent.ACTION_VIEW)
        val url =
            "https://wa.me/$mobile" + "?text=" + URLEncoder.encode(msg, "utf-8")
        i.setPackage("com.whatsapp")
        i.data = Uri.parse(url)
        if (i.resolveActivity(packageManager) != null) {
            requireContext().startActivity(i)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

注意: 这种方法仅适用于用户在其Whatsapp帐户中添加的联系人。


7
它可以打开特定的WhatsApp聊天记录,但无法发送消息。 - Nitin Karale
1
这有点像黑客行为,你匹配了WhatsApp使用的内部意图方案来启动自己的活动。这很聪明,但同时开发人员不应尝试更改目标应用程序的默认行为,该应用程序应处理数据。用户习惯于在WhatsApp启动时选择联系人,这是可以接受的。 - Sanket Berde
1
以编程方式向特定联系人发送“消息”是否是有效的方法? - Antoine Murion
@RishabhMaurya 这个方案适用于像文本消息一样直接共享图像吗? - Pioneer
@RishabhMaurya,它也适用于图像。我只是注释了这段代码// .setComponent(new ComponentName("com.whatsapp","com.whatsapp.Conversation")); - Pioneer
显示剩余10条评论

7
这种新方法是在Android上通过WhatsApp向特定联系人发送消息。有关更多信息,请查看此处
            Intent sendIntent = new Intent();
            sendIntent.setAction(Intent.ACTION_VIEW);
            String url = "https://api.whatsapp.com/send?phone=" + number + "&text=" + path;
            sendIntent.setData(Uri.parse(url));
            activity.startActivity(sendIntent);here

6
我找到了正确的方法,只要阅读本文,就会变得非常简单:http://howdygeeks.com/send-whatsapp-message-unsaved-number-android/ phone和message都是字符串。
源代码:
try {

    PackageManager packageManager = context.getPackageManager();
    Intent i = new Intent(Intent.ACTION_VIEW);

    String url = "https://api.whatsapp.com/send?phone="+ phone +"&text=" + URLEncoder.encode(message, "UTF-8");
    i.setPackage("com.whatsapp");
    i.setData(Uri.parse(url));
    if (i.resolveActivity(packageManager) != null) {
        context.startActivity(i);
    }
} catch (Exception e){
    e.printStackTrace();
}

祝您愉快!


我已经尝试了这段代码。它可以工作,但不完全是“发送”它。它只是输入了文本,现在用户需要手动按下“发送”按钮。是否可能直接发送它而无需等待用户按下“发送”按钮? - Dante
不可能实现,因为WhatsApp有自己的隐私和安全政策,并且我们的应用程序是通过意图使用它的。因此,我们无法触发“发送”按钮,我们只能配置要发送的消息和联系人,但最终用户必须拥有将我们的自动消息“发送”给他们的联系人的最后选择权。 - Crono
我明白了。如果用户允许我的应用程序模拟该位置的触摸(因为WhatsApp通常在屏幕右下角有“发送”按钮),那么这样做是否可以?如果应用程序可以直接发送消息,并且消息和联系人号码的确认将在我的应用程序中完成而不是在WhatsApp中,我可以添加一个选项。我想这不会违反WhatsApp的隐私政策,对吗? - Dante
我不确定,但如果你能实现它,请告诉我们 :) - Crono

5

太棒了,Rishabh的技巧非常有用,感谢您,我已经寻找这个解决方案三年之久。

根据上面Rishabh Maurya的答案,我实现了这段代码,可以在WhatsApp上分享文本和图片,并且运行良好。我已经将其发布在我的安卓应用程序中,如果您想要查看实际效果,请尝试我的应用程序Bill Book

请注意,在两种情况下,它都会打开WhatsApp对话(如果toNumber存在于用户的WhatsApp联系人列表中),但是用户必须单击发送按钮才能完成操作。也就是说,它可以帮助跳过选择联系人的步骤。

对于文本消息

String toNumber = "+91 98765 43210"; // contains spaces.
toNumber = toNumber.replace("+", "").replace(" ", "");

Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.putExtra("jid", toNumber + "@s.whatsapp.net");
sendIntent.putExtra(Intent.EXTRA_TEXT, message);
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setPackage("com.whatsapp");
sendIntent.setType("text/plain");
startActivity(sendIntent);

分享图片功能
String toNumber = "+91 98765 43210"; // contains spaces.
toNumber = toNumber.replace("+", "").replace(" ", "");

Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
sendIntent.putExtra("jid", toNumber + "@s.whatsapp.net");
sendIntent.putExtra(Intent.EXTRA_TEXT, message);
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setPackage("com.whatsapp");
sendIntent.setType("image/png");
context.startActivity(sendIntent);

尽情使用WhatsApp吧!


3
目前这是最佳解决方案。@Shail,如果你找到了无需按发送按钮即可发送的解决方案,请告知我。 - Saurabh Bhandari
它打开了一个空白的聊天框,如何添加消息? - Manjunath Gk

2

我们可以在Whatsapp上分享/发送消息。以下是发送文本消息到Whatsapp的示例代码:

  1. 单个用户
private void shareToOneWhatsAppUser(String message) {

    /**
     * NOTE:
     * Message is shared with only one user at a time. and to navigate back to main application user need to click back button
     */
    Intent whatsappIntent = new Intent(Intent.ACTION_SEND);
    whatsappIntent.setType("text/plain");
    whatsappIntent.setPackage("com.whatsapp");
    whatsappIntent.putExtra(Intent.EXTRA_TEXT, message);

    //Directly send to specific mobile number...
    String smsNumber = "919900990099";//Number without with country code and without '+' prifix
    whatsappIntent.putExtra("jid", smsNumber + "@s.whatsapp.net"); //phone number without "+" prefix

    if (whatsappIntent.resolveActivity(getPackageManager()) == null) {
        Toast.makeText(MainActivity.this, "Whatsapp not installed.", Toast.LENGTH_SHORT).show();
        return;
    }

    startActivity(whatsappIntent);
}
  1. 多用户
private void shareToMultipleWhatsAppUser(String message) {

    /**
     * NOTE:
     *
     * If want to send same message to multiple users then have to select the user to whom you want to share the message & then click send.
     * User navigate back to main Application once he/she select all desired persons and click send button.
     * No need to click Back Button!
     */

    Intent whatsappIntent = new Intent(Intent.ACTION_SEND);
    whatsappIntent.setType("text/plain");
    whatsappIntent.setPackage("com.whatsapp");
    whatsappIntent.putExtra(Intent.EXTRA_TEXT, message);

    if (whatsappIntent.resolveActivity(getPackageManager()) == null) {
        Toast.makeText(MainActivity.this, "Whatsapp not installed.", Toast.LENGTH_SHORT).show();
        return;
    }

    startActivity(whatsappIntent);
}

另一种实现相同目的的方法
private void shareDirecctToSingleWhatsAppUser(String message) {

    /**
     * NOTE:
     * Message is shared with only one user at a time. and to navigate back to main application user need to click back button
     */

    //Directly send to specific mobile number...
    String smsNumber = "919900000000";//Intended user`s mobile number with country code & with out '+'

    PackageManager packageManager = getPackageManager();
    Intent i = new Intent(Intent.ACTION_VIEW);

    try {
        String url = "https://api.whatsapp.com/send?phone="+ smsNumber +"&text=" + URLEncoder.encode("Test Message!", "UTF-8");
        i.setPackage("com.whatsapp");
        i.setData(Uri.parse(url));
        if (i.resolveActivity(packageManager) != null) {
            startActivity(i);
        }
    } catch (Exception e){
        e.printStackTrace();
    }
}

2
您可以使用以下代码:
 Intent sendIntent = new Intent("android.intent.action.MAIN");
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setPackage("com.whatsapp");
sendIntent.setType("text/plain");
sendIntent.putExtra("jid", "9194******22" + "@s.whatsapp.net");// here 91 is country code
sendIntent.putExtra(Intent.EXTRA_TEXT, "Demo test message");
startActivity(sendIntent);

2
这是通过WhatsApp向特定号码或未保存的号码发送消息的最佳方法。
private void openWhatsApp() {
    String smsNumber = "252634651588";
    boolean isWhatsappInstalled = whatsappInstalledOrNot("com.whatsapp");
    if (isWhatsappInstalled) {

        Intent sendIntent = new Intent("android.intent.action.MAIN");
        sendIntent.setComponent(new ComponentName("com.whatsapp", "com.whatsapp.Conversation"));
        sendIntent.putExtra("jid", PhoneNumberUtils.stripSeparators(smsNumber) + "@s.whatsapp.net");//phone number without "+" prefix

        startActivity(sendIntent);
    } else {
        Uri uri = Uri.parse("market://details?id=com.whatsapp");
        Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
        Toast.makeText(getContext(), "WhatsApp not Installed",
                Toast.LENGTH_SHORT).show();
        startActivity(goToMarket);
    }
}

private boolean whatsappInstalledOrNot(String uri) {
    PackageManager pm = Objects.requireNonNull(getContext()).getPackageManager();
    boolean app_installed = false;
    try {
        pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
        app_installed = true;
    } catch (PackageManager.NameNotFoundException e) {
        app_installed = false;
    }
    return app_installed;
}

谢谢,但这不会将文本发送到WhatsApp。所以我认为你的答案缺少了发送文本部分。 - Dika
是的,这段代码没有发送部分。当你运行这段代码时,它会启动 WhatsApp 聊天界面,然后你可以输入你的消息,最后再发送出去。谢谢。 - Jimale Abdi

0

试试这段代码

Uri uri = Uri.parse("smsto:" + "+6281122xxx");
Intent i = new Intent(Intent.ACTION_SENDTO, uri);
i.putExtra(Intent.EXTRA_TEXT, getResources().getString(R.string.default_message_wa));
i.setPackage("com.whatsapp");
startActivity(Intent.createChooser(i, ""));

你不能直接像这样在 putExtra 中放置字符串

i.putExtra(Intent.EXTRA_TEXT, "YOUR TEXT");

修改您的代码并像这样从资源中获取字符串

i.putExtra(Intent.EXTRA_TEXT, getResources().getString(R.string.default_message_wa));

0

这是对我有效的方法。

参数“body”无法被WhatsApp应用程序识别,请改用“Intent.EXTRA_TEXT”。

通过设置“phoneNumber”,您可以指定要在WhatsApp中打开的联系人。

Intent sendIntent = new Intent(Intent.ACTION_SENDTO, 
       Uri.parse("smsto:" + "" + phoneNumber + "?body=" + encodedMessage));
sendIntent.putExtra(Intent.EXTRA_TEXT, message);
sendIntent.setPackage("com.whatsapp");
startActivity(sendIntent);

0

这是我处理它的方式(更多在这里):

首先,如果你想确保能够发送消息,可以检查通讯录中的联系人是否有 WhatsApp 账户:

@RequiresPermission(permission.READ_CONTACTS)
public String getContactMimeTypeDataId(@NonNull Context context, String contactId, @NonNull String mimeType) {
    if (TextUtils.isEmpty(mimeType) || !PermissionUtil.hasPermissions(context, Manifest.permission.READ_CONTACTS))
        return null;
    ContentResolver cr = context.getContentResolver();
    Cursor cursor = cr.query(ContactsContract.Data.CONTENT_URI, new String[]{Data._ID}, Data.MIMETYPE + "= ? AND "
            + ContactsContract.Data.CONTACT_ID + "= ?", new String[]{mimeType, contactId}, null);
    if (cursor == null)
        return null;
    if (!cursor.moveToFirst()) {
        cursor.close();
        return null;
    }
    String result = cursor.getString(cursor.getColumnIndex(Data._ID));
    cursor.close();
    return result;
}

如果一切看起来正常,您可以像从网页打开一样打开它:
            final String contactMimeTypeDataId = getContactMimeTypeDataId(context, contactId, "vnd.android.cursor.item/vnd.com.whatsapp.profile");
            if (contactMimeTypeDataId != null) {
                final String whatsAppPhoneNumber = PhoneNumberHelper.normalizePhone(phoneNumber);
                String url = "https://api.whatsapp.com/send?phone="+ whatsAppPhoneNumber ;
                intent = new Intent(Intent.ACTION_VIEW,Uri.parse(url));
                intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
                .setPackage("com.whatsapp");
                startActivity(intent);
            }

你还可以在所有这些操作之前检查 WhatsApp 是否已安装(或者移除 setPackage 并检查是否有任何应用程序可以处理 Intent):
        final PackageManager packageManager = context.getPackageManager();
        final ApplicationInfo applicationInfo = packageManager.getApplicationInfo("com.whatsapp", 0);
        if (applicationInfo == null)
           return;

编辑:关于使用Uri准备Intent,我认为这种方式更好:

    @JvmStatic
    fun prepareWhatsAppMessageIntent(normalizedPhoneNumber: String?, message: String? = null): Intent {
//     example url: "https://api.whatsapp.com/send?phone=normalizedPhoneNumber&text=abc"
        val builder = Uri.Builder().scheme("https").authority("api.whatsapp.com").path("send")
        normalizedPhoneNumber?.let { builder.appendQueryParameter("phone", it) }
        message?.let { builder.appendQueryParameter("text", it) }
        return Intent(Intent.ACTION_VIEW, builder.build())
    }

或者选择另一种方式(基于此处):

    fun prepareWhatsAppMessageIntent(normalizedPhoneNumber: String?, message: String? = null): Intent {
//     example url: "https://wa.me/normalizedPhoneNumber&text=abc"
        val builder = Uri.Builder().scheme("https").authority("wa.me")
        normalizedPhoneNumber?.let { builder.appendPath(it) }
        message?.let { builder.appendQueryParameter("text", it) }
        return Intent(Intent.ACTION_VIEW, builder.build())
    }

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