- 使用eclipse导入proj.android。
- 创建包名.wxapi
-
导入微信sdk
- 创建JinHelper.java
- AppActivity.java
public static final String TAG = "NiuBuTing_Weixin_SDK";
public static final String APP_ID = "你的APP_iD";
public static IWXAPI api;
private static AppActivity instance = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
// 注册到微信
regToWx();
}
//注册到微信
private void regToWx() {
//工厂模式创建微信api
api = WXAPIFactory.createWXAPI(this, APP_ID, false);
//注册程序
api.registerApp(APP_ID);
}
//启动微信
private static boolean LaunchWX() {
boolean ret = false;
if (!api.isWXAppInstalled())
{//判断是否安装微信
Toast.makeText(instance, "没有安装微信,请先安装微信!", Toast.LENGTH_LONG).show();
return ret;
}
if (api.openWXApp())
{//判断打开微信是否成功
Log.d(TAG, "微信打开成功!");
ret = true;
}
else
{
Log.d(TAG, "微信打开失败!");
ret = false;
}
return ret;
}
//将图片解析成一个二进制数组
private byte[] bmpToByteArrar(final Bitmap bitmap, final boolean isRecycle){
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
if (isRecycle)
{
bitmap.recycle();
}
byte[] result = outputStream.toByteArray();
try
{
outputStream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return result;
}
//微信登录
public static void WXLogin(){
Log.d(TAG, "login-------------");
WXEntryActivity.ReqState = 0;
final SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo"; //这里不能改
req.state = "QTNiuBuTing"; //这里改成你自己的数据
api.sendReq(req);
}
//分享到聊天窗口
public static void WXShareMsgToFriends(final String userNickName,
final String roomNum,
final String inningsNum,
final String peopleNum,
final int playType){
//这里的参数是看你自己你需要的话就行,但是在cocos里面调用这个方法的你也传递数值过来
String strPlayType = "轮庄牛牛";
if (playType == 1) //2为轮庄
{
strPlayType = "抢庄牛牛";
}
WXEntryActivity.ReqState = 1;
//封装一个链接,点击跳转到指定网址
WXWebpageObject webpag = new WXWebpageObject();
webpag.webpageUrl = "https://www.xxxxxxxxxxxxx.com/";
//封装游戏图标
Bitmap bitmap = BitmapFactory.decodeResource(instance.getResources(), R.drawable.icon);
Bitmap thumb = Bitmap.createScaledBitmap(bitmap, 108, 108, true);
bitmap.recycle();
//封装分享内容
WXMediaMessage msg = new WXMediaMessage(webpag);
msg.thumbData = instance.bmpToByteArrar(thumb, true);
msg.title = "我是 " + userNickName; //这个是标题
msg.description = "[" + strPlayType + "]" //这个是描述
+ " 房间号:" + roomNum + "。"
+ " 局数:" + inningsNum + "。"
+ " 人数:" + peopleNum + "人。"
+ "一起来玩一玩吧!";
//封装请求
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("webpag");
req.message = msg;
req.scene = SendMessageToWX.Req.WXSceneSession;
//发送请求
api.sendReq(req);
}
//生成一个微信唯一请求标识符
private static String buildTransaction(final String type) {
return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
}
- WXEntryActivity.java
放到包名.wxapi文件夹下
WXEntryActivity.java 和 .wxapi 不要改名
包名对应的是微信记录的那个包名
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
private final String TAG = "NiuBuTing_Weixin_SDK";
public static int ReqState = -1; //0为登录, 1为分享
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AppActivity.api.handleIntent(this.getIntent(), this);
//如果没回调onResp,八成是这句没有写
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
AppActivity.api.handleIntent(intent, this);
}
// 微信发送请求到第三方应用时,会回调到该方法
@Override
public void onReq(BaseReq req) {
finish();
}
@Override
public void onResp(BaseResp resp) {
Log.d(TAG, "onResp:");
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
Log.d(TAG, "请求成功");
if (ReqState == 0) //这个是自己加用于判断是登录还是分享,你们可以去掉判断只要里面的代码就行了
{
SendAuth.Resp sendResp = (SendAuth.Resp) resp;
JniHelper.onResp(sendResp.code); //这个登录了之后用于回调cocos端函数的映射代码
Log.d(TAG, sendResp.code);
}
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
//发送取消
Toast.makeText(this, "请求取消", Toast.LENGTH_LONG).show();
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
//发送被拒绝
Toast.makeText(this, "请求被拒绝", Toast.LENGTH_LONG).show();
break;
default:
//发送返回
Toast.makeText(this, "请求返回", Toast.LENGTH_LONG).show();
break;
}
ReqState = -1;
finish();
}
}
-
AndroidManifest.xml
- WXAPIManager.h
#ifndef __WXAPIMANAGER_H__
#define __WXAPIMANAGER_H__
#include "cocos2d.h"
#include "network/HttpClient.h"
USING_NS_CC;
using namespace network;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断是不是安卓环境
#include "platform/android/jni/JniHelper.h"
#endif
typedef enum {
REQ_ERROR = 0,
REQ_SUCCESS,
CMD_ACCESS_TOKEN,
CMD_USER_INFO,
DEFAULT
}reqTag;
class WXAPIManager : Ref
{
public:
static WXAPIManager *getInstance();
//分享到好友
void sendToFriend(const char *userNickName, const char *roomNum, const char *inningsNum, const char *peopleNum, const int playType);
//微信登录
void loginWX();
public:
static WXAPIManager *_instance;
void setCode(std::string szCode);
private:
WXAPIManager();
~WXAPIManager();
std::string code;
reqTag lastTag;
};
#endif // __WXAPIMANAGER_H__
- WXAPIManager.cpp
#include "WXAPIManager.h"
WXAPIManager *WXAPIManager::_instance = nullptr;
WXAPIManager::WXAPIManager()
:lastTag(reqTag::CMD_ACCESS_TOKEN)
{
}
WXAPIManager::~WXAPIManager()
{
}
WXAPIManager *WXAPIManager::getInstance()
{
if (_instance == nullptr)
{
_instance = new(std::nothrow) WXAPIManager();
_instance->autorelease();
_instance->retain();
}
return _instance;
}
//分享给好友
void WXAPIManager::sendToFriend(const char *userNickName, const char *roomNum, const char *inningsNum, const char *peopleNum, const int playType)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) //判断是不是Android环境
JniMethodInfo minfo;
//调用java端的静态函数
bool isHave = JniHelper::getStaticMethodInfo(minfo,
"org/cocos2dx/cpp/AppActivity", //这个是固定的
"WXShareMsgToFriends", //这个是你要调用的java端的函数名
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
//后面跟的是java那边需要接收的参数
if (!isHave) {
log("jni:WXShareImgToFriends is null");
}
else {
//这里需要把参数转换为java格式
jstring jUserNickName = minfo.env->NewStringUTF(userNickName);
jstring jRoomNum = minfo.env->NewStringUTF(roomNum);
jstring jInnings = minfo.env->NewStringUTF(inningsNum);
jstring jpeopleNum = minfo.env->NewStringUTF(peopleNum);
jint jPlayType = playType;
minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID, jUserNickName, jRoomNum, jInnings, jpeopleNum, jPlayType); //开始调用函数
//删除参数
minfo.env->DeleteLocalRef(jUserNickName);
minfo.env->DeleteLocalRef(jRoomNum);
minfo.env->DeleteLocalRef(jInnings);
minfo.env->DeleteLocalRef(jpeopleNum);
}
#endif
}
//微信登录
void WXAPIManager::loginWX()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
JniMethodInfo minfo;
bool isHave = JniHelper::getStaticMethodInfo(minfo,
"org/cocos2dx/cpp/AppActivity",
"WXLogin",
"()V"); //没有参数
if (!isHave) {
log("jni:WXLogin is null");
}
else
{
minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
}
#endif
}
void WXAPIManager :: setCode(std::string szCode) {
code = szCode;
//发送code值
auto _eventDispatcher = Director::getInstance()->getEventDispatcher();
_eventDispatcher->dispatchCustomEvent("code", &szCode);
}
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
//必须是C语言的函数,因为C++的函数会有不同的符号生成规则
//1.Java_:是格式,必须加的
//2.org_cocos2dx_cpp_tools_JniHelper:是包名+类名
//3.onResp:是Andriod工程中声明的名字
//4.中间需要_分开
extern "C" {
//给android调用的native代码,微信回调后会调用这个函数
//这个代码是给安卓调用,那边传了一个code过来直接转换之后使用就行了
/*
微信的登录的流程:
1、拉起微信登录界面,用户确认之后就回调java端的回调。
2、Java端的回调执行之后根据代码在调用这个函数。
3、接下来的步骤有cocos基础的基本都知道怎么执行了
所以在cocos端首先执行的就是这里的代码。
*/
JNIEXPORT void Java_org_cocos2dx_cpp_JniHelper_onResp(JNIEnv *env, jobject thiz, jstring code)
{
/*获取code值,进行类型转换*/
const char *szCode = env->GetStringUTFChars(code, NULL);
std::string sCode = szCode;
/*调用setCode()方法*/
WXAPIManager *_twm = WXAPIManager::getInstance();
_twm->setCode(sCode);
}
}
#endif
微信登录
//微信登录 放到点击事件里
auto manager = WXAPIManager::getInstance();
manager->loginWX();
/*接收code值*/
_eventDispatcher->addCustomEventListener("code", [=](EventCustom* evn) {
std::string* strValue = (std::string*)(evn->getUserData());
Size size = Director::getInstance()->getWinSize();
code = *strValue;
/*显示所获得的code值*/
TTFConfig nameTtf("font/ffa.ttf", 16);//字体自己随便找个
nameTypeface = Label::createWithTTF(nameTtf, "423");
nameTypeface->setTextColor(Color4B::BLUE);
nameTypeface->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
nameTypeface->setPosition(size/2);
nameTypeface->setString(code);
addChild(nameTypeface);
/*然后给服务器发送code值*/
Label* nameTypeface;放到方法外面,不要放到.h文件里会打包出错。放方法里面的话Label会不显示
-
打包