项目中单独集成微信分享,集成起来还算顺利,但是还是有一些坑需要注意。下面我来说说这个具体的过程:
集成流程
1.申请你的AppID
2.下载SDK及API文档
3.搭建开发环境
4.在代码中使用开发工具包
总之,具体参考微信开放平台的接入流程,严格按照流程进行集成。点击查看集成地址
代码实现
在具体讲解代码实现前,保证你已经做到以下几点,测试才能通过:
- 应用已经通过审核
- 创建的应用包名与项目包名一致
开始实现
(1)添加依赖:
dependencies {
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}
或
dependencies {
compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}
(其中,前者包含统计功能)
(2)清单文件权限申明:
<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)将应用注册到微信:
要使你的程序启动后微信终端能响应你的程序,必须在代码中向微信终端注册你的APP_ID。(可以在程序入口Activity的onCreate回调函数处,或其他合适的地方将你的应用id注册到微信)
public void regToWeiXin() {
wxapi = WXAPIFactory.createWXAPI(WRKApplication.getContext(), appID, true);
wxapi.registerApp(appID);
}
(4)分享到微信:
- 判断当前设备是否安装微信:
/**
* 判断是否安装微信
*/
public boolean isWeiXinAppInstall() {
if (wxapi == null)
wxapi = WXAPIFactory.createWXAPI(WRKApplication.getContext(), appID);
if (wxapi.isWXAppInstalled()) {
return true;
} else {
Toast.makeText(WRKApplication.getContext(), R.string.no_install_wx, Toast.LENGTH_SHORT).show();
return false;
}
}
- 如果已安装,判断当前版本号对分享的支持情况:
不同微信版本对开放平台接口的支持(New)
发送信息:4.0及以上版本微信iPhone、Android客户端;
接收/查看信息:4.0及以上版本微信iPhone、Android、Sybiam客户端;
发送到朋友圈:4.2及以上版本微信iPhone、Android客户端;
收藏到我的收藏:5.0及以上版本微信iPhone、Android客户端。
判断版本:(这个方法只判断是否支持分享到朋友圈,其他判断类似)
/**
* 是否支持分享到朋友圈
*/
public boolean isWXAppSupportAPI() {
if (isWeiXinAppInstall()) {
int wxSdkVersion = wxapi.getWXAppSupportAPI();
if (wxSdkVersion >= TIMELINE_SUPPORTED_VERSION) {
return true;
} else {
return false;
}
} else {
return false;
}
}
- 分享数据:(支持文本、图片、表情、音频、视频、url链接、小程序)
- 分享文本:
/**
* 分享文本类型
*
* @param text 文本内容
* @param type 微信会话或者朋友圈等
*/
public void shareTextToWx(String text, int type) {
if (text == null || text.length() == 0) {
return;
}
WXTextObject textObj = new WXTextObject();
textObj.text = text;
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = textObj;
msg.description = text;
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("text");
req.message = msg;
req.scene = type;
getWxApi().sendReq(req);
}
- 分享图片(代码中开启一个线程用来加载网络图片,显示缩略图)
/**
* 分享图片到微信
*/
public void shareImageToWx(final String imgUrl, String title, String desc, final int wxSceneSession) {
Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
WXImageObject imgObj = new WXImageObject(bmp);
final WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = imgObj;
msg.title = title;
msg.description = desc;
final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
bmp.recycle();
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream imageStream = getImageStream(imgUrl);
Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
msg.mediaObject = new WXImageObject(bitmap);
thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
bitmap.recycle();
} catch (Exception e) {
e.printStackTrace();
}
msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("img");
req.message = msg;
req.scene = wxSceneSession;
getWxApi().sendReq(req);
}
}).start();
}
- 分享音频:
/**
* 分享音乐
*
* @param musicUrl 音乐资源地址
* @param title 标题
* @param desc 描述
* @param wxSceneSession
*/
public void shareMusicToWx(final String musicUrl, final String title, final String desc, final String iconUrl, final int wxSceneSession) {
WXMusicObject music = new WXMusicObject();
music.musicUrl = musicUrl;
final WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = music;
msg.title = title;
msg.description = desc;
Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
bmp.recycle();
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream imageStream = getImageStream(iconUrl);
Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
bitmap.recycle();
} catch (Exception e) {
e.printStackTrace();
}
msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("music");
req.message = msg;
req.scene = wxSceneSession;
getWxApi().sendReq(req);
}
}).start();
}
- 分享视频:
/**
* 分享视频
*
* @param videoUrl 视频地址
* @param title 标题
* @param desc 描述
* @param wxSceneSession
*/
public void shareVideoToWx(String videoUrl, String title, String desc, final String iconUrl, final int wxSceneSession) {
WXVideoObject video = new WXVideoObject();
video.videoUrl = videoUrl;
final WXMediaMessage msg = new WXMediaMessage(video);
msg.title = title;
msg.description = desc;
Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
bmp.recycle();
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream imageStream = getImageStream(iconUrl);
Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
bitmap.recycle();
} catch (Exception e) {
e.printStackTrace();
}
msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("video");
req.message = msg;
req.scene = wxSceneSession;
getWxApi().sendReq(req);
}
}).start();
}
- 分享链接:
/**
* 分享url地址
*
* @param url 地址
* @param title 标题
* @param desc 描述
* @param wxSceneSession 类型
*/
public void shareUrlToWx(String url, String title, String desc, final String iconUrl, final int wxSceneSession) {
WXWebpageObject webpage = new WXWebpageObject();
webpage.webpageUrl = url;
final WXMediaMessage msg = new WXMediaMessage(webpage);
msg.title = title;
msg.description = desc;
Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
bmp.recycle();
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream imageStream = getImageStream(iconUrl);
Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
bitmap.recycle();
} catch (Exception e) {
e.printStackTrace();
}
msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("webpage");
req.message = msg;
req.scene = wxSceneSession;
getWxApi().sendReq(req);
}
}).start();
}
这几种分享已经满足项目需求,所以没有做小程序分享。如果有需要直接参看开发平台Demo即可。
(5)分享后接受微信的回调:WXEntryActivity类实现
- 在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类,该类继承自Activity(必须确保申请时的包名下,否则接收不到信息)
- 在manifest文件里面加上exported属性,设置为true
<activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:theme="@style/AppTheme.Fullscreen.Translucent" />
回调接受处理:
public class WRKWxEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI api;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 通过WXAPIFactory工厂,获取IWXAPI的实例
api = WRKShareUtil.getInstance().getWxApi();
//注意:
//第三方开发者如果使用透明界面来实现WXEntryActivity,需要判断handleIntent的返回值,如果返回值为false,则说明入参不合法未被SDK处理,应finish当前透明界面,避免外部通过传递非法参数的Intent导致停留在透明界面,引起用户的疑惑
try {
api.handleIntent(getIntent(), this);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq baseReq) {
// System.out.println(baseReq);
}
@Override
public void onResp(BaseResp baseResp) {
int result;
switch (baseResp.errCode) {
case BaseResp.ErrCode.ERR_OK:
result = R.string.errcode_success;
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
result = R.string.errcode_cancel;
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
result = R.string.errcode_deny;
break;
case BaseResp.ErrCode.ERR_UNSUPPORT:
result = R.string.errcode_unsupported;
break;
default:
result = R.string.errcode_unknown;
break;
}
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
finish();
}
}
到这基本上就实现分享功能了,如果这样,那你就厉害了。这里我再说一下在集成时遇到的问题:
集成问题与解决:
- 点击分享后,出现 “ 不合法的参数,无法分享到微信。返回到没有审核的应用 ” ,出现这个问题是因为我把APP_ID写错了。APP_ID一般为一个以wx开头的18个字符的字符串。
- 分享了多条数据,发现有几条数据点击分享,不能把微信调起来。这个时候你就需要查看你分享的数据是否符合微信规定的限制条件。要对应限制条件,进行处理。来看一下源码:(检查发送时的缩略图大小是否超过32k)
final boolean checkArgs() {
if(this.getType() == 8 && (this.thumbData == null || this.thumbData.length == 0)) {
Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, thumbData should not be null when send emoji");
return false;
} else if(this.thumbData != null && this.thumbData.length > '耀') {
Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, thumbData is invalid");
return false;
} else if(this.title != null && this.title.length() > 512) {
Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, title is invalid");
return false;
} else if(this.description != null && this.description.length() > 1024) {
Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, description is invalid");
return false;
} else if(this.mediaObject == null) {
Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, mediaObject is null");
return false;
} else if(this.mediaTagName != null && this.mediaTagName.length() > 64) {
Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, mediaTagName is too long");
return false;
} else if(this.messageAction != null && this.messageAction.length() > 2048) {
Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, messageAction is too long");
return false;
} else if(this.messageExt != null && this.messageExt.length() > 2048) {
Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, messageExt is too long");
return false;
} else {
return this.mediaObject.checkArgs();
}
}
看看你没有分享成功的原因有没有这些,要是仔细看日志的伙伴应该也能发现这个问题。所以我在代码中做出了处理:
String title = mShareData.getTitle();
if (title != null && title.length() > 512)
title = title.substring(0, 511);
String desc = mShareData.getDesc();
if (desc != null && desc.length() > 1024)
desc = desc.substring(0, 1023);
总结:
最终集成成功了,遇到的问题也基本解决了。微信的集成与其他的集成大致看一下,套路都是一样的。想一想要是集成其他的,遇到的这些坑,其他分享应该也会有。比如说限制条件。
由于项目有多个端(APP_ID有多个),都需要分享功能。所以把分享功能放到了公共库,但是这样公共库不能访问到各个端的APP_ID,所以我将APP_ID放到各个端的清单文件中,以mete_data的形式在运行时动态获取。如果不懂这一流程,可以看我的一篇文章:运行时动态获取清单数据
希望这个分享能对你有帮助,收尾!
网友评论