如何从我的 Android 应用程序通过 WhatsApp 向特定联系人发送消息?

Posted

技术标签:

【中文标题】如何从我的 Android 应用程序通过 WhatsApp 向特定联系人发送消息?【英文标题】:How can I send message to specific contact through WhatsApp from my android app? 【发布时间】:2016-07-20 14:02:37 【问题描述】:

我正在开发一个 android 应用程序,我需要从 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”,尽管选择了联系人。

【问题讨论】:

查看FAQ 目前尚不支持通过intent打开whatsapp中的特定联系人。 @Johny Moo 你能向特定联系人发送消息吗? 【参考方案1】:

有办法。确保您提供的联系人必须作为不带前缀“+”的意图字符串传递。国家代码应作为电话号码的前缀。

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

注意:将“YOUR_PHONE_NUMBER”替换为您要向其发送消息的联系人。

这里是sn-p:

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

更新:

上述技巧不能用于添加任何特定消息,因此这是新方法。在此处以国际格式传递用户 mobile,不带任何括号、破折号或加号。示例:如果用户是印度并且他的手机号码是 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 中添加的联系人 帐户。

【讨论】:

它打开了特定的应用程序聊天,但不发送消息。 这是一种 hack,您正在匹配 whatsapp 使用的内部意图方案来启动自己的活动。这是天才,但同时开发人员不应该尝试更改应该处理数据的目标应用程序的默认行为。用户习惯于在whatsapp启动时选择联系人,没关系。 以编程方式向whatsapp中的特定联系人发送“消息”是否有效?? @Antoine 大概是这样。它将打开选定用户的聊天活动,并通过意图传递消息。 @RishabhMaurya 是否可以添加文本消息?【参考方案2】:

这种新方法,通过 Android 中的 whatsapp 向特定联系人发送消息。更多信息请查看here

            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

【讨论】:

【参考方案3】:

我找到了正确的方法,并且在您阅读本文后很简单:http://howdygeeks.com/send-whatsapp-message-unsaved-number-android/

电话和消息都是字符串。

源代码:

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

享受吧!

【讨论】:

我试过这段代码。它有效,但并不完全是“发送”它。它输入了文本,现在用户需要手动按下“发送”按钮。是否可以直接发送而不等待用户按下“发送”按钮? 这是不可能的,因为 WhatsApp 有自己的隐私和安全策略,并且我们的应用程序正在通过意图使用它,因此我们无法触发“发送”按钮,我们只能配置消息和联系人以发送它,但最终用户必须有最后的选择才能将我们的自动消息“发送”给他们的联系人。 我明白了。如果用户允许我的应用程序(如果应用程序可以直接发送消息和消息和联系电话的确认将在我的应用程序而不是 whatsapp 中完成)?我想这并不违反 whatsapp 的隐私政策。对吗? 我不确定,但如果你能做到,请告诉我们:)【参考方案4】:

很棒的 hack Rishabh,非常感谢,我从过去 3 年开始一直在寻找这个解决方案。

根据上面 Rishabh Maurya 的回答,我已经实现了这段代码,它适用于 WhatsApp 上的文本和图像共享。我已经在我的 android 应用中发布了这个,所以如果你想实时看到它,试试我的应用 Bill Book

请注意,在这两种情况下,它都会打开一个 whatsapp 对话(如果用户 whatsapp 联系人列表中存在 toNumber),但用户必须单击发送按钮才能完成操作。这意味着它有助于跳过联系人选择步骤。

对于短信

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 的乐趣!

【讨论】:

这是迄今为止最好的解决方案。@Shail 如果您在不按发送按钮的情况下获得发送解决方案,请告诉我 打开一个空白聊天框,如何添加消息?【参考方案5】:

您可以使用此代码:

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

【讨论】:

【参考方案6】:

这是通过 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。所以我认为你的答案是错过发送文本部分。 是的,没有发送部分,当您运行此代码时,它会启动 WhatsApp 聊天,然后您可以编写您的消息,然后您可以发送它。谢谢【参考方案7】:

我们可以分享/发送消息到什么应用程序。下面是在Whats-app上发送短信的示例代码

    单用户
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);

    多用户
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();
    

【讨论】:

【参考方案8】:

这对我有用。

whatsapp 应用程序不会使参数“body”变红,请改用“Intent.EXTRA_TEXT”。

通过设置“电话号码”,您可以指定要在 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);

【讨论】:

【参考方案9】:
Uri mUri = Uri.parse("smsto:+90000900000");
Intent mIntent = new Intent(Intent.ACTION_SENDTO, mUri);
mIntent.setPackage("com.whatsapp");
mIntent.putExtra("chat",true);
startActivity(Intent.createChooser(mIntent, "Share with"));

非常适合从我的 Android 应用向 WhatsApp 上的特定联系人发送消息

【讨论】:

【参考方案10】:

试试这个代码

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

【讨论】:

【参考方案11】:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_VIEW); 
String url ="https://wa.me/your number"; 
sendIntent.setData(Uri.parse(url));
startActivity(sendIntent);

【讨论】:

【参考方案12】:

这是我的做法(更多 here):

首先,如果您想确保可以发送消息,您可以检查此人的通讯录上是否有 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())
    

或替代(基于here):

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

【讨论】:

【参考方案13】:

尝试使用Intent.EXTRA_TEXT 而不是sms_body 作为您的额外密钥。根据 WhatsApp 的文档,这是您必须使用的。

来自their website的例子:

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);

他们的示例使用 Intent.ACTION_SEND 而不是 Intent.ACTION_SENDTO,所以我不确定 WhatsApp 是否支持通过意图系统直接发送给联系人。一些快速测试应该可以让您确定这一点。

【讨论】:

我试过你的代码,它工作正常,但我需要自动选择联系人。 您使用的是ACTION_SEND 还是ACTION_SENDTO?如果是后者,则意味着 WhatsApp 无法正确支持该意图,您对此无能为力。 我正在使用 ACTION_SENDTO,我认为参数发生了变化, 是的,那你就不走运了。 问题是:“我需要从 WhatsApp 向特定联系人发送消息”。那么为什么这是公认的答案呢?

以上是关于如何从我的 Android 应用程序通过 WhatsApp 向特定联系人发送消息?的主要内容,如果未能解决你的问题,请参考以下文章

如何从我的 android 应用程序打开 youtube 应用程序主页活动?

如何从我的 Android 设备直接在 Helix 服务器上录制视频?

如何将文档从我的 mongodb 数据库发送到 android 应用程序?

如何从我的 Android 应用程序中的所有目录中获取所有 pdf 文件

如何从我的应用程序发送应用程序邀请(通过whatsapp、hike、消息)

Android:如何从我的 APK 中将文件系统挂载到 RW 中? (当然是有根的)