1.做好微信开放平台的审核工作
第一步:创建自己的微信开放平台账号并且提交自己的应用等待审核
审核通过之后就会如上图所示,审核已通过。一般应用审核通过之后只会有微信分享和收藏的功能:
某些接口是要收费的,具体要看自己的需求了,再提交应用的时候有很重要的两点,第一就是包名,安卓程序唯一标识就是包名,也是安装在手机上的唯一标识,这样系统才会识别出来这是两种不同的应用。还有一个就是应用签名:把apk文件装在手机上用微信开放平台的签名检测工具,输入自己的包名就可以得出应用签名了,然后把这个签名提交到微信开放平台上。(这里有一点需要特别注意,到后面出现无法登陆微信的情况很有可能是本地签名和微信开放平台的签名不一致所导致的,导出自己的apk时,要注意需要用keystore文件来对apk进行签名,这样带有keystore文件的apk以后就可以用这个keystore来签名了,尽量不要用debug.keystore。在以后微信开放平台上面的应用签名也可以修改)
在eclipse里面打开这个窗口进行keystore的导入(首先要自己创建一个keystore文件):
选择keystore文件之后点击apply,然后ok就可以了。
2.编写本地代码
由于我的项目是Cocos项目,要想调用Java层的微信SDK接口必须在本地编写逻辑代码,然后借助Jni来调用Java层的代码:
self.Button_login:addTouchEventListener(function ( sender,eventType )
if eventType == ccui.TouchEventType.ended then
print('==================登录 LoginScene:btnEvent()')
self:lodingAnimation()
game.anysdk:login_native()
end
end)
然后走到anysdk:login_native里面(也可以直接走到Jni里面)
function AnySdk:login_native()
local function LoginServer()
local function callBack()
MissionManager.getMission('login_mission','main_mission'):sendData(MDM_GR_LOGON,SUB_GP_LOGON_ACCOUNTS)
end
MissionManager.connect(LOGIN_SERVER_NAME,LOGIN_SERVER_IP,LOGIN_SERVER_PORT,callBack)
end
if device.platform == "android" or device.platform == "ios" then
local access_token = cc.UserDefault:getInstance():getStringForKey("access_token", "")
local openid = cc.UserDefault:getInstance():getStringForKey("openid", "")
if access_token ~= "" and openid ~= "" then
self:getWeixinInfo(access_token,openid,LoginServer)
else
JniFun:create():longinWX(APP_ID,AppSecret)
end
else
--self:getWeixinInfo("", "", LoginServer)
local function callBack()
MissionManager.getMission('login_mission','main_mission'):sendData(MDM_GR_LOGON,SUB_GP_REGISTER_ACCOUNTS)
end
MissionManager.connect(LOGIN_SERVER_NAME,LOGIN_SERVER_IP,LOGIN_SERVER_PORT,callBack)
end
end
然后进入到JniFun:loginWX里面:
#include "JniFun.h"
#include "cocos2d.h"
#include "CCLuaEngine.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include
#include "platform/android/jni/JniHelper.h"
#include "jubaosdk/ShellApiJni.h"
#endif
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
#include "IosHelper.h"
#endif
#define JAVA_CLASSNAME "com/wx/Native"
using namespace cocos2d;
void JniFun::longinWX(const char* APP_ID,const char* AppSecret)
{
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
JniMethodInfo minfo;
bool isHave = JniHelper::getStaticMethodInfo(minfo,JAVA_CLASSNAME,"LoginWX","(Ljava/lang/String;Ljava/lang/String;)V");
if (isHave)
{
jstring jAPP_ID = minfo.env->NewStringUTF(APP_ID);
jstring jAppSecret = minfo.env->NewStringUTF(AppSecret);
minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,jAPP_ID,jAppSecret);
minfo.env->DeleteLocalRef(jAPP_ID);
minfo.env->DeleteLocalRef(jAppSecret);
minfo.env->DeleteLocalRef(minfo.classID);
cocos2d::log("JniFun call LoginWX over!");
}
else
{
//NoticeMsg::Instance().ShowLogon(false);
cocos2d::log("JniFun call LoginWX error!");
}
#endif
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
cocos2d::log("IosHelper::sendAuthRequest!");
IosHelper::sendAuthRequest();
#endif
}
在JniFun里面就用到了cocos封装好的JniHelper类,通过上面的代码才会真正调用到Java里面的微信API方法
其中这里需要注意,微信的方法编写是有约束的,打个比方,如果你的项目包名是com.zhijiegame.www,那么你就要在src下面先新建一个com.zhijiegame.www.wxapi的包,这个命名规则是微信要求的,然后在这个包下面创建一个WXEntryAvtivity的类:
package com.ydqp.yjmj.wxapi;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import com.wx.Native;
import com.wx.Util;
import com.tencent.mm.sdk.constants.ConstantsAPI;
import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.modelmsg.SendAuth;
import com.tencent.mm.sdk.modelmsg.SendMessageToWX;
import com.tencent.mm.sdk.modelmsg.ShowMessageFromWX;
import com.tencent.mm.sdk.modelmsg.WXAppExtendObject;
import com.tencent.mm.sdk.modelmsg.WXImageObject;
import com.tencent.mm.sdk.modelmsg.WXMediaMessage;
import com.tencent.mm.sdk.modelmsg.WXTextObject;
import com.tencent.mm.sdk.modelmsg.WXWebpageObject;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
public class WXEntryActivity extends Activity implements IWXAPIEventHandler{
public static String Tag = "YZH";
private static final int TIMELINE_SUPPORTED_VERSION = 0x21020001;
private static WXEntryActivity sContext = null;
public static boolean bLogonWX = false;
public static boolean isShareWX = false;
public static boolean isShareURL = false;
private static final int THUMB_SIZE = 150;
public static final String APP_ID = "*****************************";
public static final String AppSecret = "******************************";
private IWXAPI api;
private static final int SceneSession = 0;
private static final int SceneTimeline = 1;
public static String ReqWxLogin = "ReqWxLogin";
public static String ReqWxShareImg = "ReqWxShareImg";
public static String ReqWxShareTxt = "ReqWxShareTxt";
public static String ReqWxShareUrl = "ReqWxShareUrl";
public static String ReqWXPay = "ReqWXPay";
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
sContext = this;
Log.d(Tag,"onCreate");
Log.d(Tag,"onCreate1");
Intent intent = getIntent();
Log.d(Tag,"onCreate2");
api = WXAPIFactory.createWXAPI(this,APP_ID, false);
Log.d(Tag,"onCreate3");
api.registerApp(APP_ID);
Log.d(Tag,"onCreate4");
api.handleIntent(intent, this);
Log.d(Tag,"onCreate5");
if (intent.hasExtra(ReqWxLogin))
{
reqLogin();
}
else if(intent.hasExtra(ReqWxShareImg))
{
isShareWX=true;
Log.d(Tag,"ReqWxShareImg");
String ImgPath = intent.getStringExtra("ImgPath");
int nType = intent.getIntExtra("ShareType",0);
reqShareImg(ImgPath,nType);
}
else if(intent.hasExtra(ReqWxShareTxt))
{
isShareWX=true;
Log.d(Tag,"ReqWxShareTxt");
String ShareText = intent.getStringExtra("ShareText");
int nType = intent.getIntExtra("ShareType",0);
reqShareTxt(ShareText,nType);
}
else if(intent.hasExtra(ReqWxShareUrl))
{
isShareWX=true;
Log.d(Tag,"ReqWxShareUrl");
String ShareUrl = intent.getStringExtra("ShareUrl");
String ShareTitle = intent.getStringExtra("ShareTitle");
String ShareDesc = intent.getStringExtra("ShareDesc");
int nType = intent.getIntExtra("ShareType",0);
reqShareUrl(ShareUrl,ShareTitle,ShareDesc,nType);
}
Log.d(Tag,"onCreate fnish");
finish();
}
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
Log.d(Tag,"1");
setIntent(intent);
Log.d(Tag,"2");
api.handleIntent(intent, this);
Log.d(Tag,"3");
}
public void reqLogin()
{
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "123";
api.sendReq(req);
Log.d(Tag,"reqLogin");
if(!api.openWXApp())
{
Toast.makeText(this, "请先安装微信客户端", Toast.LENGTH_LONG).show();
}
}
public void reqShareImg(String ImgPath,int nType)
{
File file = new File(ImgPath);
if (!file.exists())
{
Log.d(Tag,"reqShare file not exists:"+ImgPath);
return;
}
Bitmap bmp = BitmapFactory.decodeFile(ImgPath);
WXImageObject imgObj = new WXImageObject(bmp);
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = imgObj;
Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, 128, 72, true);
bmp.recycle();
msg.thumbData = Util.bmpToByteArray(thumbBmp, true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("img");
req.message = msg;
if(nType==SceneTimeline )
{
req.scene = SendMessageToWX.Req.WXSceneTimeline;
}
else if(nType==SceneSession )
{
req.scene = SendMessageToWX.Req.WXSceneSession;
}
api.sendReq(req);
Log.d(Tag,"reqShare Ok:"+ImgPath);
}
public void reqShareTxt(String text,int nType)
{
WXTextObject textObj = new WXTextObject();
textObj.text = text;
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = textObj;
// msg.title = "Will be ignored";
msg.description = text;
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("text");
req.message = msg;
if(nType==SceneTimeline )
{
req.scene = SendMessageToWX.Req.WXSceneTimeline;
}
else if(nType==SceneSession )
{
req.scene = SendMessageToWX.Req.WXSceneSession;
}
api.sendReq(req);
Log.d(Tag,"reqShareTxt Ok:"+text);
}
public native void Share();
public void reqShareUrl(String url, String title,String desc,int nType)
{
WXWebpageObject textObj = new WXWebpageObject();
textObj.webpageUrl = url;
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = textObj;
msg.title = title;
msg.description = desc;
//if(nType==SceneTimeline )
{
AssetManager asm=getAssets();
String s = "weixin_share_icon.png";
InputStream is = null;
try {
is = asm.open(s);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//asm.open("");
Bitmap bmp=BitmapFactory.decodeStream(is);
URL res = this.getClass().getResource("icon.png");
Log.d(Tag,"r:"+res);
if (null != bmp) {
Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, 80, 80, true);
bmp.recycle();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
thumbBmp.compress(Bitmap.CompressFormat.PNG, 100, baos);
msg.thumbData = baos.toByteArray();
}
}
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("webpage");
req.message = msg;
if(nType==SceneTimeline )
{
isShareURL = false;
req.scene = SendMessageToWX.Req.WXSceneTimeline;
}
else if(nType==SceneSession )
{
isShareURL = false;
req.scene = SendMessageToWX.Req.WXSceneSession;
}
api.sendReq(req);
Log.d(Tag,"reqShareUrl Ok:"+url);
}
public void reqShareTxtCB(String text,int nType)
{
// send appdata with no attachment
WXAppExtendObject appdata = new WXAppExtendObject("lallalallallal", "filePath");
boolean bValue = appdata.checkArgs();
if (!bValue)
{
Log.d(Tag,"reqShareTxtCB Error:"+text);
}
WXMediaMessage msg = new WXMediaMessage();
msg.title ="11";
msg.description = "22";
msg.mediaObject = appdata;
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("appdata");
req.message = msg;
if(nType==SceneTimeline )
{
req.scene = SendMessageToWX.Req.WXSceneTimeline;
}
else if(nType==SceneSession )
{
req.scene = SendMessageToWX.Req.WXSceneSession;
}
api.sendReq(req);
Log.d(Tag,"reqShareTxtCB Ok:"+text);
}
@Override
public void onReq(BaseReq req)
{
switch (req.getType())
{
case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
Log.d(Tag,"onReq:COMMAND_GETMESSAGE_FROM_WX");
break;
case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
Log.d(Tag,"onReq:COMMAND_SHOWMESSAGE_FROM_WX");
break;
default:
break;
}
Log.d(Tag,"onReq:"+req.getType());
}
@Override
public void onResp(BaseResp resp) {
String result = null;
Log.d(Tag,"errCode:"+resp.errCode);
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
Log.d(Tag,"OK");
result = "操作成功";
if(!isShareWX)
{
isShareWX=!isShareWX;
result ="操作成功";
String code = ((SendAuth.Resp) resp).code;
String Url =code;
Log.d(Tag,"OK1");
Log.d(Tag,Url);
Native.WxLoginGetAccessToken(Url);
Log.d(Tag,"OK2");
}
Log.d(Tag,"Start Share");
if(isShareURL)
{
Log.d(Tag,"Shareing");
Share();
result ="分享成功";
}
Log.d(Tag,"Over Share");
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
Log.d(Tag,"quxiao");
result ="用户取消";
Native.WxLoginGetAccessToken("ERR_USER_CANCEL");
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
Log.d(Tag,"jujue");
result ="用户拒绝";
Native.WxLoginGetAccessToken("ERR_AUTH_DENIED");
break;
default:
Log.d(Tag,"buzhidao");
result ="未知错误";
Native.WxLoginGetAccessToken("REE_Unknow");
break;
}
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
}
private String buildTransaction(final String type) {
return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
}
}
把你申请得到的APP_ID和AppSecret填上去,就可以了,这里只是做了简单的登录功能,其他部分都差不多,调用不同的函数就可以了。