如何將消息發送給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\n");

}

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\n");

}

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有了更進一步的認識了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM