zoukankan      html  css  js  c++  java
  • 如何将消息发送给Whatsapp联系人

    如何将消息发送给Whatsapp联系人

    (由于本人喜欢word文档编辑,不喜欢网络编辑,所以仍然提供pdf版文档,方便查阅http://files.cnblogs.com/franksunny/send_msg_to_Whatsapp.pdf

    Whatsapp官网上没有找到在Android上进行消息发送相关的信息,但是有一个iOS相关的帖子https://www.whatsapp.com/faq/iphone/23559013,原以为用它的URLAndroid上也是可以使用的,结果试了下不行,看来错误地把URL当作URI了。

    基础功能实现

    后来根据Android IntentIntent Filters的官方文档说明(如果英文不太好,参考中文的翻译文档,链接为下面的第二个地址):

    http://developer.android.com/guide/components/intents-filters.html

    http://wiki.eoe.cn/page/Intents_and_Intent_Filters.html#comment

    就想着查看了下WhatsappManifest配置文件,看看能不能找出点蛛丝马迹,结果发现有如下的Activity信息

    <activity

    android:name=".ContactPicker"

    android:configChanges="0x00000FB0"

    >

    <intent-filter

    >

    <action

    android:name="android.intent.action.PICK"

    >

    </action>

    <category

    android:name="android.intent.category.DEFAULT"

    >

    </category>

    <category

    android:name="com.whatsapp"

    >

    </category>

    </intent-filter>

    <intent-filter

    >

    <action

    android:name="android.intent.action.CREATE_SHORTCUT"

    >

    </action>

    </intent-filter>

    <intent-filter

    >

    <action

    android:name="android.intent.action.SEND"

    >

    </action>

    <category

    android:name="android.intent.category.DEFAULT"

    >

    </category>

    <data

    android:mimeType="audio/*"

    >

    </data>

    <data

    android:mimeType="video/*"

    >

    </data>

    <data

    android:mimeType="image/*"

    >

    </data>

    <data

    android:mimeType="text/plain"

    >

    </data>

    <data

    android:mimeType="text/x-vcard"

    >

    </data>

    </intent-filter>

    <intent-filter

    >

    <action

    android:name="android.intent.action.SEND_MULTIPLE"

    >

    </action>

    <category

    android:name="android.intent.category.DEFAULT"

    >

    </category>

    <data

    android:mimeType="audio/*"

    >

    </data>

    <data

    android:mimeType="video/*"

    >

    </data>

    <data

    android:mimeType="image/*"

    >

    </data>

    </intent-filter>

    </activity>

    至于是不是这个Activity,简单写个测试就验证了,既然找到了这个对象,怎么将信息发送进去,继续google下“com.whatsapp”和“com.whatsapp.ContactPicker”字符串,结果就发现如下一些热帖:

    http://stackoverflow.com/questions/6394173/androidpick-action-in-intent

    http://stackoverflow.com/questions/19081654/send-to-specific-contact-whatsapp

    http://stackoverflow.com/questions/15462874/sending-message-through-whatsapp

    从中发现如果想要发送文字信息给Whatsapp进行Whatsapp内消息的发送,可以利用的intent中两个缺省的字段Intent.EXTRA_TEXTIntent.EXTRA_SUBJECT,于是就按照“android.intent.action.SEND”这个Intent Filter做下如下的代码尝试。

    public static boolean sendWhatsApp(Context ctx, String text){

    boolean sendOk = false;

    if(checkApkExist(ctx, "com.whatsapp")){

    Intent vIt = new Intent("android.intent.action.SEND");

    vIt.setPackage("com.whatsapp");

    vIt.setType("text/plain");

    if(!Util.IsNullOrEmpty(text)){

    vIt.putExtra(Intent.EXTRA_TEXT, "This is a simple test");

    vIt.putExtra(Intent.EXTRA_SUBJECT, "Subject");

    }

    ctx.startActivity(vIt);

    sendOk = true;

    }

    return sendOk;

    }

     

    private static boolean checkApkExist(Context ctx, String packageName) {

    if (packageName == null || "".equals(packageName)) 

    return false;

    try {

    ApplicationInfo info = ctx.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);

    if(info != null){

    return true;

    }else{

    return false;

    }

    }catch (NameNotFoundException e){

    return false; 

    }

    }

    上述的checkApkExist方法是用于判断当前是否有安装相应包程序的,发送效果如下:

     

    假如上述代码中,去除vIt.setPackage("com.whatsapp");这段代码之后,就会出现一个选择框的效果,这个就和很多程序中做分享的效果一致了,下面选择环聊做了简单测试。

      

    假如要发图片的话也可以通过分享Deja头像的方式,来实现,下面将代码简单整理了下,就先省略了具体的判断代码:

    public static void shareImageToWhatsapp(Activity ctx, Bitmap shareBitmap, String subject, String text) {

    Intent intent = new Intent(Intent.ACTION_SEND);

    intent.setPackage("com.whatsapp");

    intent.setType("image/*");

    Uri imageUri = Uri.parse(MediaStore.Images.Media.insertImage(ctx.getContentResolver(), shareBitmap, null, null));

    intent.putExtra(Intent.EXTRA_SUBJECT, subject);

    intent.putExtra(Intent.EXTRA_TEXT, text);

    intent.putExtra(Intent.EXTRA_STREAM, imageUri);

    ctx.startActivity(Intent.createChooser(intent, ctx.getTitle()));

    }

    扩展深入

    以前对IntentIntent Filters可以说是一知半解的,对于官方的提供的上面的那个API文档,也没有吃透,不过经过这次的机会,对于IntentIntent Filter可以说有了一个比较进一步的认识。

    Intent分为显式和隐式两种,简而言之,显式就是已经明显告知了所要调用的组件名称,而隐式是没有明确告知组件名称的调用方式,所以说显式调用时虽然也是通过Intent,但是显式调用不进行Intent Filter条件过滤;隐式调用组件时,就要通过组建在Manifest中设置的Intent Filter来进行匹配了。

    显式调用有两种,一种是程序内部明确知道是具体的Activity,然后类似下述的直接调用:

    startActivity(new Intent(this, ShareTargetActivity.class));

    这种调用显然是能够通过lib或源码import到现有文件的方式。另外一种显式调用就是通过IntentsetComponent方法来显示调用,比如我们已经知道Whatsapp的组件名了,我们就可以通过以下方式调用:

    public static boolean sendWhatsApp(Context ctx, String text){

    boolean sendOk = false;

    if(checkApkExist(ctx, "com.whatsapp")){

    Intent vIt = new Intent();

    ComponentName comp = new ComponentName( "com.whatsapp", "com.whatsapp.ContactPicker");

    vIt.setComponent(comp);

    if(!Util.IsNullOrEmpty(text)){

    vIt.putExtra(Intent.EXTRA_TEXT, text);

    vIt.putExtra(Intent.EXTRA_SUBJECT, "Subject ");

    }

    ctx.startActivity(vIt);

    sendOk = true;

    }

    return sendOk;

    }

    显式Intent时,压根就不用设置任何跟Intent Filter相关的参数,如果写了反而证明是不明真相的画蛇添足。

    隐式Intent的调用就必须查看Manifest里面的配置了,而且根据API文档的说明,隐式Intent在进行过滤时,actioncategory和、data是必须进行匹配的,至于extraflag选项只是负责传参数,不作为过滤条件。而一个Intent Filter只有一个actioncategory则是可以叠加的,至于data还是看API文档吧,不做过多展看了,通常我们都是忽略掉category,在这里正好给我们提供了一个category的例子,因为Whatsapp里面的第一个Intent Filter,即如下内容

    <intent-filter

    >

    <action

    android:name="android.intent.action.PICK"

    >

    </action>

    <category

    android:name="android.intent.category.DEFAULT"

    >

    </category>

    <category

    android:name="com.whatsapp"

    >

    </category>

    </intent-filter>

    我们可以通过下述方法进行隐式调用,就可以通过这个Filter的过滤,将参数正确传给ContactPicker这个Activity,以下给出简单代码:

    public static boolean sendWhatsApp(Context ctx, String text) {

    boolean sendOk = false;

    if (checkApkExist(ctx, "com.whatsapp")) {

    Intent vIt = new Intent("android.intent.action.PICK");

    vIt.addCategory("com.whatsapp");

    // vIt.setType("text/plain");

    if (!Util.IsNullOrEmpty(text)) {

    vIt.putExtra(Intent.EXTRA_TEXT, text);

    vIt.putExtra(Intent.EXTRA_SUBJECT, "Subject ");

    }

    ctx.startActivity(vIt);

    sendOk = true;

    }

    return sendOk;

    }

    注意在上述这个例子中,注释掉的setType代码是必须注释的,否则程序将因为找不到Activity组件而报android.content.ActivityNotFoundException的异常错误。

    同样我们也不能通过以下方式进行调用

    public static boolean sendWhatsApp(Context ctx, String text){

    boolean sendOk = false;

    if(checkApkExist(ctx, "com.whatsapp")){

    Intent vIt = new Intent("android.intent.action.SEND_MULTIPLE");

    vIt.setPackage("com.whatsapp");

    vIt.setType("text/plain");

    if(!Util.IsNullOrEmpty(text)){

    vIt.putExtra(Intent.EXTRA_TEXT, text);

    vIt.putExtra(Intent.EXTRA_SUBJECT, "Subject");

    }

    ctx.startActivity(vIt);

    sendOk = true;

    }

    return sendOk;

    }

    对照下Manifest,应该就一目了然了,总体上,通过这个例子,应该能对IntentIntent Filter有了更进一步的认识了。

     

  • 相关阅读:
    c++ 优化的动态数组 Vector
    C++ 重载赋值运算符
    k8s中引入外部服务
    MySQL----mysql_secure_installation 安全配置向导
    elk参考连接
    限制不同的用户操作k8s的资源
    tcpdump 抓包命令使用教程
    日志管理——rsyslog、logrotate
    lsyncd配置文件详细说明
    Systemd 服务配置文件(转载)
  • 原文地址:https://www.cnblogs.com/franksunny/p/3629276.html
Copyright © 2011-2022 走看看