最近在研究cocoscreator创建的游戏接入微信登录和分享功能。开始想用anysdk,但是anysdk用起来比较繁琐,所以就采用手动接入微信sdk的方法来接入。基本思想是用js来调用android函数的方式。cocoscreator工程打包成android工程。注意一定要修改包名为你在微信平台注册的包名com.xxx.xxx,打包成release版本。然后打开build目录下的安卓屎丢丢工程,可看到org.cocos2dx.javascript的目录下面有AppActivity和SDKWrapper俩个文件,AppActivity就是游戏对应到android的主活动。要使用微信登录,先去微信开放平台注册获取Appid和appSecret这些请自行百度。本文只写重要步骤。
1 导入微信sdk libammsdk.jar和open_sdk_r5509_lite.jar
2 新建一个pakage,名字是你的包名com.xxx.xxx.wxapi,然后在里面新建WxEntryActivity这个类,内容如下:
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
//private IWXAPI wxApi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_wxentry);
//wxApi = WXAPIFactory.createWXAPI(this, Define.WX_APPID, false);
//如果分享的时候,该界面没有开启,那么微信开始这个activity时,会调用onCreate,所以这里要处理微信的返回结果
//wxApi.handleIntent(getIntent(), this);
AppActivity.wxApi.handleIntent(this.getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//如果分享的时候,该已经开启,那么微信开始这个activity时,会调用onNewIntent,所以这里要处理微信的返回结果
setIntent(intent);
//wxApi.handleIntent(intent, this);
AppActivity.wxApi.handleIntent(intent, this);
// finish();
}
// 微信发送请求到第三方应用时,会回调到该方法
@Override
public void onReq(BaseReq baseReq) {
}
// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
@Override
public void onResp(BaseResp baseResp) {
//关于数值的类型,微信官方文档里有写:发送OpenAPI Auth验证的数值为:1;分享消息到微信的数值为2
if (baseResp.getType() == 2) {
//转态码和授权的一样
String result = "";
switch (baseResp.errCode) {
//同意授权
case BaseResp.ErrCode.ERR_OK:
result = "分享成功";
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
result = "分享取消";
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
result = "分享被拒绝";
break;
default:
result = "分享返回";
break;
}
// Toast.makeText(this, result, Toast.LENGTH_LONG).show();
finish();
}
if (baseResp.getType() == 1) {
switch (baseResp.errCode) {
//同意授权
case BaseResp.ErrCode.ERR_OK:
SendAuth.Resp resp = (SendAuth.Resp) baseResp;
Define.resp = resp;//微信登录成功,保存resp到全局变量里面
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
case BaseResp.ErrCode.ERR_AUTH_DENIED:
default:
//MTACountUtil.registerUser(this, "weixin", "fail");
break;
}
finish();
}
}
}
3、AppActivity里面定义静态全局变量wxApi以及初始化函数regToWx(),将regToWx()写入页面的onCreate函数中去
public static IWXAPI wxApi;
public void regToWx() {
//IWXAPI 是第三方app和微信通信的openapi接口
wxApi = WXAPIFactory.createWXAPI(this, Define.WX_APPID, false);
//将应用注册到微信
wxApi.registerApp(Define.WX_APPID);
}
4、登录函数,当这个函数被调用时会弹出微信的登录页面。
public static void loginByWeiXin(int val) {
//mProgressDialog.show();
// send oauth request
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "wechat_sdk_aifuns";
wxApi.sendReq(req);
}
5、微信登录成功后会调用WxEntryActivity页面,已经在这里获取到了resp,resp.code可以用来获取微信的access_token。获取access_token的函数:
private void getWeiXinAccessToken(String code) {
//ToastUtil.showShortToast(this,"getWeiXinAccessToken,code:"+code);
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + "appid=" + Define.WX_APPID + "&secret=" + Define.WX_APPSECRET + "&code=" + code + "&grant_type=authorization_code";
OkHttpHelper.getinstance().post(this, url, null, new OkHttpBaseCallBack() {
@Override
public void onRequestBefore() {
}
@Override
public void onFailure(Request request, Exception e) {
Toast.makeText(instance, "请求微信token失败",Toast.LENGTH_LONG).show();
}
@Override
public void onSuccess(Response response, Object o) {
try {
JSONObject jsonObject = new JSONObject((String) o);
String token = jsonObject.optString("access_token");
String openId = jsonObject.optString("openid");
getWeiXinInfo(token,openId);
} catch (Exception e) {
}
}
@Override
public void onError(Response response, int errorCode, Exception e) {
}
});
}
将getWeiXinAccessToken写入到onResume里面:
if(Define.resp != null)
{
String code = Define.resp.code;
getWeiXinAccessToken(code);
}
6、上面函数中有个函数getWeiXinInfo是用来获取微信名称、头像之类的。
void getWeiXinInfo(String token,String id)
{
String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+token+"&openid="+id;
OkHttpHelper.getinstance().post(this, url, null, new OkHttpBaseCallBack() {
@Override
public void onRequestBefore() {
}
@Override
public void onFailure(Request request, Exception e) {
}
@Override
public void onSuccess(Response response, Object o) {
try{
JSONObject jsonObject = new JSONObject((String) o);
wxFlag = true;
openId = jsonObject.optString("openid");
nickname = jsonObject.optString("nickname");
avatar = jsonObject.optString("headimgurl");
sex = jsonObject.optInt("sex");//0:未知 1:男 2:女
//mProgressDialog.dismiss();
}catch (Exception e)
{
}
}
@Override
public void onError(Response response, int errorCode, Exception e) {
}
});
}
7、将获取到的值封装成函数以备cocoscreator中调用
public static boolean getWxFlag(int x)
{
return wxFlag;
}
public static void setWxFlag(boolean val){wxFlag=val;}
public static String getOpenId(int x){return openId;}
public static String getNickname(int x){return nickname;}
public static String getAvatar(int x){return avatar;}
public static int getSex(int x){return sex;}
8、游戏端登录函数
login :function() {
cc.log("login...");
this.loginFlag = true;
jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "loginByWeiXin","(I)V",0);
//Global.sendWxLoginMsg("hello")
},
9、login调用后,就会调用java端一系列函数,直到最终获取到微信id,名称,头像,性别等信息。得到这些信息后,怎么通知js端呢?由于坑爹的cocoscreator在java调用js端还不成熟,所以不采用java调用js的方法,而是在js端采用查询的方式来查看登录是否成功。js的update函数中写入查询代码:
update:function(dt)
{
if(this.loginFlag)
{
var wxFlag = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "getWxFlag","(I)Z",0);
if(wxFlag)
{
this.loginFlag = false;
this.openId = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "getOpenId","(I)Ljava/lang/String;",0);
this.nickname = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "getNickname","(I)Ljava/lang/String;",0);
this.avatar = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "getAvatar","(I)Ljava/lang/String;",0);
this.sex = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "getSex","(I)I",0);
jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "setWxFlag","(Z)V",false);
this.labName.string = this.nickname;
if(this.sex == 1)
this.labSex.String = "男";
else if(this.sex == 2)
this.labSex.String = "女";
this.labId.string = this.openId;
this.getUserPic(this.avatar);
}
}
},
至此微信登录已经完毕。
10、微信分享比微信登录简单蛮多。在java里面写函数
public static void shareWX(boolean isShareFriend)
{
Bitmap bitmap = BitmapFactory.decodeResource(instance.getResources(), R.mipmap.ic_launcher);
Bitmap thumbBmp = Bitmap.createScaledBitmap(bitmap, 150, 150, true); //缩略图大小
WXWebpageObject webpage = new WXWebpageObject();
webpage.webpageUrl = "http://baidu.com";
WXMediaMessage msg = new WXMediaMessage(webpage);
msg.title = "share wx";
msg.description = "this is my share wx";
msg.thumbData = bmpToByteArray(thumbBmp, true); // 设置缩略图
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = String.valueOf(System.currentTimeMillis());
req.message = msg;
req.scene = isShareFriend ? SendMessageToWX.Req.WXSceneSession : SendMessageToWX.Req.WXSceneTimeline;
wxApi.sendReq(req);
}
private static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
if (needRecycle) {
bmp.recycle();
}
byte[] result = output.toByteArray();
try {
output.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
js端调用share函数来实现分享。
share:function()
{
jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "shareWX","(Z)V",true);
}