公司專案需要對接微信分享,本來之前準備對接友盟分享的,但友盟的分享實際引數太多,而我又只需要對接一個微信分享,於是便是選擇總結對接官方的
順便把微信SDK的APPID申請的流程也一起記錄了
前往微信公眾平臺,使用企業認證的開發者賬號進行登入,提交應用包名和簽名指紋檔案,可以生成一個appId,有了此appId賬號才能有侯勳的操作
通過輸入命令可檢視簽名檔案的md5等資訊:
keytool -list -v -keystore qj_test.keystore
注意:上述輸完命令後需要輸入密碼,密碼不會顯示出來,密碼正確則會出現下面的相關md5等資訊了
微信平臺比較坑的就是,它要求輸入不要帶:
號,且還要小寫的md5數值,我們稍微處理一下:我比較懶,就寫了幾行程式碼處理了,程式碼如下:
//改為你的md5即可
String md5 = "73:95:50:FB:F9:A9:A6:A3:F2:74:E0:25:64:EB:E7:48";
String result = md5.replaceAll(":", "").toLowerCase();
System.out.println(result);
輸出結果複製一下,就得到了符合規範的md5了
implementation 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.0'
官方檔案提供的寫法是不固定版本號的,我這裡覺得還是固定版本號比較好,需要依賴中央倉庫即可
// APP_ID 替換為你的應用從官方網站申請到的合法appID
private static final String APP_ID = "wx88888888";
// IWXAPI 是第三方 app 和微信通訊的 openApi 介面
private IWXAPI api;
private void regToWx(Context context) {
// 通過 WXAPIFactory 工廠,獲取 IWXAPI 的範例
api = WXAPIFactory.createWXAPI(context, APP_ID, true);
// 將應用的 appId 註冊到微信
api.registerApp(APP_ID);
//建議動態監聽微信啟動廣播進行註冊到微信
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 將該 app 註冊到微信
api.registerApp(APP_ID);
}
}, new IntentFilter(ConstantsAPI.ACTION_REFRESH_WXAPP));
}
之後在分享的Activity或Application中進行初始化,呼叫regToWx()
,如
regToWx(MainActivity.this)
PS: 這裡可以看下下面提到的工具類封裝
經過上面的步驟,我們已經能夠使用微信分享了,使用IWXAPI那個物件即可,具體可以檢視檔案WXMediaMessage (微信媒體訊息內容)說明 | 微信開放檔案
api.sendReq(req);
不過需要注意一下Android11的適配,需要在AndroidManifest.xml
宣告
<queries>
<!-- 指定微信包名-->
<package android:name="com.tencent.mm" />
</queries>
這裡我是封裝了一個工具類,原始碼在下一章節,主要封裝了分享文字,圖片,視訊和網頁連結,至於分享小程式和分享音樂檔案沒有需求,就暫時沒有對接,各位可以參考的完善即可
這裡順便補充一下,由於我自己個人沒法成功申請到微信應用平臺的APPID,於是我就是使用了另外專案的的APPID來進行測試
測試的發現,只要你使用同個簽名檔案,同時,把build.gradle裡面的applicationId改成填寫的包名,微信分享就是能夠正常的使用
舉個例子,我們有一個應用包名為com.starsone.test
的應用已經申請到了APPID
這個時候,我們另外個專案,包名與其不同,但我們想要測試一下分享功能,可以進行以下的操作:
修改app模組裡的build.gradle,將applicationId改為com.starsone.test
包名,並使用相同的簽名檔案打包即可使用同個APPID測試分享功能了,如下圖所示:
如果專案中需要對分享成功或失敗進行監聽,來進行進一步的邏輯處理,可以按照微信官方的檔案新增一個WxEntryActivity實現
由於我開發的專案暫時無需,所以沒怎麼研究,這裡稍微簡單的補充一下:
我們需要建立一個WXEntryActivity
作為回撥的接收,WXEntryActivity
沒有頁面,主要實現微信的回撥介面IWXAPIEventHandler
即可,程式碼如下:
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
@Override
public void onReq(BaseReq baseReq) {
}
@Override
public void onResp(BaseResp baseResp) {
}
}
<activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:launchMode="singleTask"
android:taskAffinity="com.tyky.share"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
這裡,注意,Activity是要處於你當前包名下的wxapi資料夾,如我自己的例子,當前包名是com.tyky.share
,也是我在新建一層wxapi包名,並將Activity放在裡面,如下圖所示
這裡由於我沒有用到,所以就沒有在方法裡補充對應的邏輯了
邏輯解釋如下:
通過
api.sendReq(req)
分享內容,傳送的請求會將回撥一次onReq()
方法,之後微信分享完成(成功或取消)之後,會將響應結果將回撥到onResp()
方法
工具類用到了以下兩個依賴,記得先匯入
implementation 'org.apache.commons:commons-lang3:3.9'
// Android的工具類 https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README-CN.md
implementation 'com.blankj:utilcodex:1.30.6'
PS:微信SDK依賴也不要忘記哦!
package com.tyky.share.utils;
import android.graphics.Bitmap;
import com.blankj.utilcode.util.EncodeUtils;
import com.blankj.utilcode.util.ImageUtils;
import com.blankj.utilcode.util.MetaDataUtils;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXVideoObject;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import java.io.File;
import static com.tencent.mm.opensdk.modelmsg.SendMessageToWX.Req.WXSceneSession;
import static com.tencent.mm.opensdk.modelmsg.SendMessageToWX.Req.WXSceneTimeline;
/**
* 參考檔案 [WXMediaMessage (微信媒體訊息內容)說明 | 微信開放檔案](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Share_and_Favorites/Android.html)
* 微信分享工具類(沒有對接小程式和音樂)
*
* @author starsone
*/
public class WxUtils {
//從meta裡讀取微信平臺的appId
public static String appId = "";
// IWXAPI 是第三方 app 和微信通訊的 openApi 介面 初始化在ShareInitializer類中
public static IWXAPI api;
/**
* 分享文字
*
* @param text 文字內容(長度需大於 0 且不超過 10KB)
* @param flag 0:好友 1:朋友圈
* @param title 分享標題
* @param description 分享描述
*/
public static void shareText(String text, int flag, String title, String description) {
//初始化一個 WXTextObject 物件,填寫分享的文字內容
WXTextObject textObj = new WXTextObject();
textObj.text = text;
//用 WXTextObject 物件初始化一個 WXMediaMessage 物件
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = textObj;
msg.title = title;
msg.description = description;
sendMessage(msg, flag);
}
/**
* 分享圖片
*
* @param imgBase64 圖片base64資料
* @param flag 0:好友 1:朋友圈
* @param title 分享標題
* @param description 分享描述
*/
public static void sharePicture(String imgBase64, int flag, String title, String description) {
//base64資料處理
String data = imgBase64;
if (data.contains("base64,")) {
data = org.apache.commons.lang3.StringUtils.substringAfter(data, "base64,");
}
byte[] bytes = EncodeUtils.base64Decode(data);
Bitmap bitmap = ImageUtils.bytes2Bitmap(bytes);
//使用file存放,突破微信分享的限制
File file = ImageUtils.save2Album(bitmap, Bitmap.CompressFormat.PNG);
sharePictureByImgFilePath(file.getPath(), flag, title, description);
}
/**
* 分享圖片
*
* @param imgFilePath 圖片本地路徑
* @param flag 0:好友 1:朋友圈
* @param title 分享標題
* @param description 分享描述
*/
public static void sharePictureByImgFilePath(String imgFilePath, int flag, String title, String description) {
//初始化一個 WXImageObject 物件,填寫分享圖片
WXImageObject wxImageObject = new WXImageObject();
wxImageObject.imagePath = imgFilePath;
//用 WXTextObject 物件初始化一個 WXMediaMessage 物件
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = wxImageObject;
msg.title = title;
msg.description = description;
sendMessage(msg, flag);
}
/**
* 分享視訊
*
* @param videoUrl 視訊連結
* @param flag 0:好友 1:朋友圈
* @param title 分享標題
* @param description 分享描述
*/
public static void shareVideo(String videoUrl, int flag, String title, String description) {
//初始化一個 WXImageObject 物件,填寫分享圖片
WXVideoObject wxImageObject = new WXVideoObject();
wxImageObject.videoUrl = videoUrl;
//用 WXTextObject 物件初始化一個 WXMediaMessage 物件
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = wxImageObject;
msg.title = title;
msg.description = description;
sendMessage(msg, flag);
}
/**
* 分享網頁
*
* @param webUrl 網頁連結
* @param flag 0:好友 1:朋友圈
* @param title 分享標題
* @param description 分享描述
*/
public static void shareWeb(String webUrl, int flag, String title, String description) {
//初始化一個 WXImageObject 物件,填寫分享圖片
WXWebpageObject wxImageObject = new WXWebpageObject();
wxImageObject.webpageUrl = webUrl;
//用 WXTextObject 物件初始化一個 WXMediaMessage 物件
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = wxImageObject;
msg.title = title;
msg.description = description;
sendMessage(msg, flag);
}
/**
* @param msg 分享內容實體資料
* @param flag 0:好友 1:朋友圈
*/
private static void sendMessage(WXMediaMessage msg, int flag) {
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = String.valueOf(System.currentTimeMillis()); //transaction欄位用與唯一標示一個請求
req.message = msg;
//朋友圈:WXSceneTimeline
//對談:WXSceneSession
if (flag == 1) {
req.scene = WXSceneTimeline;
} else {
req.scene = WXSceneSession;
}
//呼叫 api 介面,傳送資料到微信
api.sendReq(req);
}
}
工具類使用的時候,記得在註冊的時候一起進行初始化,把上述第三步的初始化方法程式碼改為如下面:
private void regToWx(Context context) {
String APP_ID = WxUtils.appId;
// 通過 WXAPIFactory 工廠,獲取 IWXAPI 的範例
WxUtils.api = WXAPIFactory.createWXAPI(context, APP_ID, true);
// 將應用的 appId 註冊到微信
WxUtils.api.registerApp(APP_ID);
//建議動態監聽微信啟動廣播進行註冊到微信
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 將該 app 註冊到微信
WxUtils.api.registerApp(APP_ID);
}
}, new IntentFilter(ConstantsAPI.ACTION_REFRESH_WXAPP));
}
之後在Application或Activity進行初始化,其他步驟不變
1、設定簽名的坑
解決:一定要MD5、小寫、不要帶冒號,最好用官方給的簽名獲取工具。
2、沒有註冊API
解決:API是執行重複註冊的,並且也不是耗時任務,所以不妨放在Activity的onCreate下面,記得寫這個。
3、分享的圖示
解決:分享的圖示大小不能超過32K,要是jpg格式。
3、分享圖示自己能看到,好友看不到
解決:修改分享的標題和內容,不要觸及微信的敏感詞檢測系統,多試幾下。
4、沒有回撥
解決:一定要注意WXEntryActivity的包名路徑是否正確,已經設定export=true
5、確定了問題4後還是調不起來
你確定有在WXEntryActivity的onCreate裡面註冊API並且呼叫 api.handleIntent(getIntent(), this);? 估計你沒有吧?
6、回撥到其他頁面
解決:沒辦法直接回撥到其他頁面,但可以通過廣播、EventBus等通知的實現來通知其他頁面重新整理,同時結束WXEntryActivity的頁面。