A complete Android Wechat Sharing Integration Strategy
Preparations before development
1. Log on to Wechat Open Platform to fill in your own developer information and wait for approval for the next step.
Open Platform Address: https://open.weixin.qq.com/
2. Create your own APP on the open platform (under the account approved by the previous audit)
Open Platform Creates Its Application _________2.1 Fill in the package name when creating the application that loves you. Please get the corresponding value of the application Id field in the build.gradle file of your project.
2.2 Fill in your signature. Please do not add the signature directly from the command line. The specific rules are as follows.
2.2.1 Download APP Officially Provided by Wechat
https://res.wx.qq.com/open/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk
2.2.2 After installing the mobile phone, fill in the package name and the corresponding value of the application Id field.
2.2.3 Get the corresponding signature
Following is the approved APP
3. If you need to change the signature information of your own APP, please remember to test and use it the next day. Wechat background needs time to change, remember!
Note that if you change your signature or package name temporarily, it won't work at that time (that is, you don't need the function of Wechat in APP). You may have to wait a day for it to work!!!!! The lesson of blood!!
II. Integrated sdk
1. Introducing dependency libraries into the project build.gradle
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:1.1.6'
2. Setting permission access in Android Manifest. XML file
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
3. Register with Wechat
To enable your program to respond to your program after it starts, you must register your id with the Wechat terminal in the code. (As shown in the figure below, you can register your application id with Wechat at the onCreate callback function of the Program Entry Activity or other suitable places. An example of the registration function is shown in the following figure.
IWXAPI api = WXAPIFactory.createWXAPI(this, WeChartConfig.APP_ID, false);
4. For sharing, I made the following encapsulation, please use it according to your own needs.
It combines Weixin pure text sharing, Weixin pure picture sharing, music sharing, video sharing, web page sharing, etc. Please create this file by yourself and call it according to the instructions.
Notice in sharing that the size of the picture should not be larger than 32k for all the positions of the matched pictures. Please handle them by yourself.
Oversize error checkArgs fail, thumbData is invalid
Solution: Compressing bitmap size
5. Current activity implements the IWXAPIEventHandler interface, setting up callbacks to receive successful or failed sharing
// When a wechat sends a request to a third party application, it calls back to this method. @Override public void onReq(BaseReq req) { Toast.makeText(this, "openid = " + req.openId, Toast.LENGTH_SHORT).show(); switch (req.getType()) { case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX: break; case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX: break; case ConstantsAPI.COMMAND_LAUNCH_BY_WX: break; default: break; } } // The response of a third-party application to a request sent to Wechat after processing is called back to this method. @Override public void onResp(BaseResp resp) { Toast.makeText(this, "openid = " + resp.openId, Toast.LENGTH_SHORT).show(); if (resp.getType() == ConstantsAPI.COMMAND_SENDAUTH) { Toast.makeText(this, "code = " + ((SendAuth.Resp) resp).code, Toast.LENGTH_SHORT).show(); } String result = ""; switch (resp.errCode) { case BaseResp.ErrCode.ERR_OK: result = "Share success"; break; case BaseResp.ErrCode.ERR_USER_CANCEL: result = "Sharing was cancelled"; break; case BaseResp.ErrCode.ERR_AUTH_DENIED: result = "Sharing rejected"; break; default: result = "Unknown anomaly"; break; } ToastUtils.showToastShort(result); }
Sharing tool class code is as follows
package china.test.utils.wechartshareutil; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Rect; import android.support.annotation.IntDef; import android.text.TextUtils; import com.tencent.mm.opensdk.modelmsg.SendMessageToWX; import com.tencent.mm.opensdk.modelmsg.WXAppExtendObject; import com.tencent.mm.opensdk.modelmsg.WXImageObject; import com.tencent.mm.opensdk.modelmsg.WXMediaMessage; import com.tencent.mm.opensdk.modelmsg.WXMusicObject; 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.ByteArrayOutputStream; import java.io.File; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.URL; import china.test.utils.BitmapUtils; import china.test.utils.FileUtils; /** * Created by benchengzhou on 2018/6/21 17:34 . * Author's mailbox: mappstore@163.com * Function Description: Wechat Sharing Tool Class * Class name: WechartShareUtil * Remarks: */ public class WechartShareUtil { //Share in the circle of friends public static final int SHARE_PATH_WX_SCENETIMELINE = 0; //Share with Wechat Friends public static final int SHARE_PATH_WX_SCENESESSION = 1; @IntDef({SHARE_PATH_WX_SCENETIMELINE, SHARE_PATH_WX_SCENESESSION}) @Retention(RetentionPolicy.SOURCE) public @interface WXSendWay { } private WechartShareUtil() { } private static class getInstance2 { private static WechartShareUtil wechartShareUtil = new WechartShareUtil(); } public static WechartShareUtil getInstance() { return getInstance2.wechartShareUtil; } /** * Wechat Pure Text Sharing * * @param message * @param api * @throws IllegalArgumentException * @throws NullPointerException */ public void shareTextMessageByWeChart(String message, @WXSendWay int sendWay, IWXAPI api) throws IllegalArgumentException, NullPointerException { //...To-do if (message == null || message.length() == 0) { throw new IllegalArgumentException("messge=null, Wechat Text Sharing Contents Can't Be Empty"); } if (api == null) { throw new NullPointerException("IWXAPI=null Illegal null pointer"); } // Initialize a WXTextObject object WXTextObject textObj = new WXTextObject(); textObj.text = message; // Initialize a WXMediaMessage object with a WXTextObject object WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = textObj; // The title field does not work when sending text-type messages // msg.title = "Will be ignored"; msg.description = message; // Construct a Req SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("text"); // The transaction field is used to uniquely identify a request req.message = msg; //Choose to share with friends or conversations req.scene = (sendWay == SHARE_PATH_WX_SCENETIMELINE) ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; // req.openId = getOpenId(); // Ignore this value temporarily // Call api interface to send data to wechat api.sendReq(req); } /** * Wechat Shares Pictures Through Binary Stream * * @param bmp * @param sendWay * @param bitmapOption * @param api */ public void shareImageByBinary(Bitmap bmp, @WXSendWay int sendWay, bitmapOption bitmapOption, IWXAPI api) { if (bmp == null || bmp.getByteCount() == 0) { throw new IllegalArgumentException("bmp=null, The content of pictures shared by Wechat should not be empty"); } if (api == null) { throw new NullPointerException("IWXAPI=null Illegal null pointer"); } WXImageObject imgObj = new WXImageObject(bmp); WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = imgObj; Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, bitmapOption.getBitmapWith(), bitmapOption.getBitmapHeight(), true); bmp.recycle(); msg.thumbData = bmpToByteArray(thumbBmp, true); // set thumbnail SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("img"); req.message = msg; req.scene = (sendWay == SHARE_PATH_WX_SCENETIMELINE) ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; // req.openId = getOpenId(); api.sendReq(req); } /** * Share a picture of a local presence * Here's a pit. WXMediaMessage: checkArgs fail, thumbData is invalid * demo The original method of converting bitmap objects into byte data bytes has some problems. Look at the Wechat instructions. The cover image should be within 32k. * * @param imagPath * @param sendWay * @param bitmapOption * @param api */ public void shareImageByFilePath(String imagPath, @WXSendWay int sendWay, bitmapOption bitmapOption, IWXAPI api) { File imgFile = new File(imagPath); if ((!imgFile.exists()) || imgFile.isDirectory()) { throw new IllegalArgumentException("imagPath, The picture path shared by Wechat does not exist"); } if (api == null) { throw new NullPointerException("IWXAPI=null Illegal null pointer"); } WXImageObject imgObj = new WXImageObject(); imgObj.setImagePath(imagPath); WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = imgObj; Bitmap bmp = BitmapFactory.decodeFile(imagPath); Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, bitmapOption.getBitmapWith(), bitmapOption.getBitmapHeight(), true); msg.thumbData = bmpToByteArray(thumbBmp, true); bmp.recycle(); SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("img"); req.message = msg; req.scene = (sendWay == SHARE_PATH_WX_SCENETIMELINE) ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; api.sendReq(req); } public void shareImageByNetWork(final String imageUrl, @WXSendWay final int sendWay, final bitmapOption bitmapOption, final IWXAPI api) { if (TextUtils.isEmpty(imageUrl) || !(imageUrl.startsWith("http://") || imageUrl.startsWith("https://"))) { throw new IllegalArgumentException("Illegal Internet Picture Path"); } if (api == null) { throw new NullPointerException("IWXAPI=null Illegal null pointer"); } new Thread(new Runnable() { @Override public void run() { try { WXImageObject imgObj = new WXImageObject(); imgObj.imagePath = imageUrl; WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = imgObj; Bitmap bmp = BitmapFactory.decodeStream(new URL(imageUrl).openStream()); Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, bitmapOption.getBitmapWith(), bitmapOption.getBitmapHeight(), true); bmp.recycle(); msg.thumbData = bmpToByteArray(thumbBmp, true); SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("img"); req.message = msg; req.scene = (sendWay == SHARE_PATH_WX_SCENETIMELINE) ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; api.sendReq(req); } catch (Exception e) { e.printStackTrace(); } } }).start(); } /** * Wechat Shares an Internet Song * * @param musicUrl Network album path * @param thumbBmp Album cover * @param title Album name * @param description Album description * @param sendWay * @param bitmapOption Album cover * @param api */ public void shareMusicByNetWork(String musicUrl, Bitmap thumbBmp, String title, String description, @WXSendWay int sendWay, bitmapOption bitmapOption, IWXAPI api) { if (TextUtils.isEmpty(musicUrl) || !(musicUrl.startsWith("http://") || musicUrl.startsWith("https://"))) { throw new IllegalArgumentException("Illegal Network Resource Path"); } if (TextUtils.isEmpty(title)) { title = "The title of the song is unknown"; } if (TextUtils.isEmpty(description)) { title = "The description is unknown"; } if (api == null) { throw new NullPointerException("IWXAPI=null Illegal null pointer"); } WXMusicObject music = new WXMusicObject(); music.musicUrl = musicUrl; WXMediaMessage msg = new WXMediaMessage(); msg.mediaObject = music; msg.title = title; msg.description = description; msg.thumbData = bmpToByteArray(thumbBmp, true); SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("music"); req.message = msg; req.scene = (sendWay == SHARE_PATH_WX_SCENETIMELINE) ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; api.sendReq(req); } /** * Wechat Shares Network Video * * @param videoUrl * @param thumbBmp Video Cover Map * @param title Video Cover Description Title * @param description Video Cover Description Content * @param sendWay * @param api */ public void shareVideoByNetWork(String videoUrl, Bitmap thumbBmp, String title, String description, @WXSendWay int sendWay, IWXAPI api) { if (TextUtils.isEmpty(videoUrl) || !(videoUrl.startsWith("http://") || videoUrl.startsWith("https://"))) { throw new IllegalArgumentException("Illegal Network Resource Path"); } if (api == null) { throw new NullPointerException("IWXAPI=null Illegal null pointer"); } WXVideoObject video = new WXVideoObject(); video.videoUrl = videoUrl; WXMediaMessage msg = new WXMediaMessage(video); if (!TextUtils.isEmpty(title)) { // title = unknown video name; msg.title = title; } if (!TextUtils.isEmpty(description)) { // description = video content unknown; msg.description = description; } msg.thumbData = bmpToByteArray(thumbBmp, true); SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("video"); req.message = msg; req.scene = (sendWay == SHARE_PATH_WX_SCENETIMELINE) ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; api.sendReq(req); } /** * Wechat Sharing Web Page * * @param webpageUrl The Path of Web Page * @param thumbBmp Album cover * @param title Name * @param description describe * @param sendWay * @param api */ public void shareWebpageByNetWork(String webpageUrl, Bitmap thumbBmp, String title, String description, @WXSendWay int sendWay, IWXAPI api) { if (TextUtils.isEmpty(webpageUrl) || !(webpageUrl.startsWith("http://") || webpageUrl.startsWith("https://"))) { throw new IllegalArgumentException("Illegal Network Resource Path"); } if (api == null) { throw new NullPointerException("IWXAPI=null Illegal null pointer"); } WXWebpageObject webpage = new WXWebpageObject(); webpage.webpageUrl = webpageUrl; WXMediaMessage msg = new WXMediaMessage(webpage); if (!TextUtils.isEmpty(title)) { // title = unknown video name; msg.title = title; } if (!TextUtils.isEmpty(description)) { // description = video content unknown; msg.description = description; } msg.thumbData = bmpToByteArray(thumbBmp, true); SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("webpage"); req.message = msg; req.scene = (sendWay == SHARE_PATH_WX_SCENETIMELINE) ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; api.sendReq(req); } /** * Send an APP internal message with attachments. After clicking on the message, the user can directly open the corresponding APP and generate the corresponding message callback. * Users need to practice the corresponding callback method by themselves * * @param thumbBmp * @param title * @param description * @param extInfo * @param filePath * @param sendWay * @param api */ public void shareAppInnerIncludeFileLocal(Bitmap thumbBmp, String title, String description, String extInfo, String filePath, @WXSendWay int sendWay, IWXAPI api) { if (api == null) { throw new NullPointerException("IWXAPI=null Illegal null pointer"); } final WXAppExtendObject appdata = new WXAppExtendObject(); if (!TextUtils.isEmpty(extInfo)) { appdata.extInfo = extInfo; } final WXMediaMessage msg = new WXMediaMessage(); msg.setThumbImage(thumbBmp); if (!TextUtils.isEmpty(title)) { msg.title = title; } if (!TextUtils.isEmpty(description)) { msg.description = description; } if (!TextUtils.isEmpty(filePath)) { appdata.fileData = FileUtils.readFromFile(filePath, 0, -1); } msg.mediaObject = appdata; SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("appdata"); req.message = msg; req.scene = (sendWay == SHARE_PATH_WX_SCENETIMELINE) ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; api.sendReq(req); } /** * Without APP internal messages with attachments, users can directly open the corresponding APP and generate corresponding message callbacks after clicking on the message. * Users need to practice the corresponding callback method by themselves * * @param title * @param description * @param extInfo * @param sendWay * @param api */ public void shareAppInnerNoLocationfile(String title, String description, String extInfo, @WXSendWay int sendWay, IWXAPI api) { if (api == null) { throw new NullPointerException("IWXAPI=null Illegal null pointer"); } final WXAppExtendObject appdata = new WXAppExtendObject(); appdata.extInfo = extInfo; final WXMediaMessage msg = new WXMediaMessage(); msg.title = title; msg.description = description; msg.mediaObject = appdata; SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = buildTransaction("appdata"); req.message = msg; req.scene = (sendWay == SHARE_PATH_WX_SCENETIMELINE) ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession; api.sendReq(req); } /** * Getting Sharing Categories * * @param type * @return */ private String buildTransaction(final String type) { return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis(); } /** * bmp Converting to bmpToByteArray * Minimize the bytearray returned * @param bmp * @param needRecycle * @return */ public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) { int i; int j; if (bmp.getHeight() > bmp.getWidth()) { i = bmp.getWidth(); j = bmp.getWidth(); } else { i = bmp.getHeight(); j = bmp.getHeight(); } Bitmap localBitmap = Bitmap.createBitmap(i, j, Bitmap.Config.RGB_565); Canvas localCanvas = new Canvas(localBitmap); while (true) { localCanvas.drawBitmap(bmp, new Rect(0, 0, i, j), new Rect(0, 0, i, j), null); if (needRecycle) bmp.recycle(); ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream(); localBitmap.compress(Bitmap.CompressFormat.JPEG, 100, localByteArrayOutputStream); localBitmap.recycle(); byte[] arrayOfByte = localByteArrayOutputStream.toByteArray(); try { localByteArrayOutputStream.close(); return arrayOfByte; } catch (Exception e) { // F.out(e); } i = bmp.getHeight(); j = bmp.getHeight(); } } /** * Wechat Sharing Picture Size */ public static class bitmapOption { private int bitmapWith = 150; private int bitmapHeight = 150; public int getBitmapWith() { return bitmapWith; } public void setBitmapWith(int bitmapWith) { this.bitmapWith = bitmapWith; } public int getBitmapHeight() { return bitmapHeight; } public void setBitmapHeight(int bitmapHeight) { this.bitmapHeight = bitmapHeight; } } }