cocos2d-x C++ (Android)集成第三方微信分享

时间:2023-02-09 12:51:50

ShareSDK Android for cocos2d-x

此文档为ShareSDK Android for cocos3.x的版本,如您集成的是2.X的版本文档请到这里:cocos2.x集成文档

1.1、下载ShareSDK的cocos2d-x工具类

打开Github下载C2DX-For-ShareSDK-3.X项目(注意:这里下载的只供cocos2d-x 3.x使用)。将项目中的C2DXShareSDK目录拷贝到你的项目中。

(注意:要想运行我们提供的demo,必须先要下载cocos2dx的框架,打开proj.android 文件夹里的工程,然后把我们的相关代码文件导入到现在工程就行)
 

1.2、修改AppDelegate文件

打开“AppDelegate.cpp”文件,导入头文件“C2DXShareSDK.h”。如:

#include "C2DXShareSDK.h"

在AppDelegate::applicationDidFinishLaunching方法中,加入下面代码进行初始化ShareSDK并配置社交平台信息。还要记得写上c++的命名空间,代码如下:

using namespace cn::sharesdk; 

bool AppDelegate::applicationDidFinishLaunching()
{
    //初始化ShareSDK
    this->initShareSDKConfig();
}

void AppDelegate::initShareSDKConfig()
{
    //平台配置信息
    __Dictionary *totalDict = __Dictionary::create();

    //以新浪微博为例子,如需在代码配置平台的信息,各个平台对应字段的key请参考,assets>ShareSDK.xml里面的字段
    __Dictionary *sinaWeiboConf= __Dictionary::create();
    sinaWeiboConf->setObject(__String::create("1"), "Id");
    sinaWeiboConf->setObject(__String::create("1"), "SortID");
    sinaWeiboConf->setObject(__String::create("568898243"), "AppKey");
    sinaWeiboConf->setObject(__String::create("38a4f8204cc784f81f9f0daaf31e02e3"), "AppSecret");
    sinaWeiboConf->setObject(__String::create("http://www.sharesdk.cn"), "RedirectUrl");
    sinaWeiboConf->setObject(__String::create("false"), "ShareByAppClient");
    sinaWeiboConf->setObject(__String::create("true"), "Enable");
    stringstream sina;
    sina << cn::sharesdk::C2DXPlatTypeSinaWeibo;     totalDict->setObject(sinaWeiboConf, sina.str());

    /*Android可以代码里面配置凭他信息,也在assets>ShareSDK.xml里面配置信息,需要读取XMl的话,registerAppAndSetPlatformConfig第一个参数需要传""空字符串;*/
    cn::sharesdk::C2DXShareSDK::registerAppAndSetPlatformConfig("android1101", totalDict);
}

 

 

 

注意:其中配置社交平台信息中的配置项说明,请参考《社交平台配置项说明》文档。

1.3、分享内容

先构造分享内容结构,代码如下(注意文件编码如果不为utf-8会导致所有的内容都为Null):

Dictionary *content = Dictionary::create();
content -> setObject(String::create("这是一条测试内容"), "content");
content -> setObject(String::create("http://img0.bdstatic.com/img/image/shouye/systsy-11927417755.jpg"), "image");
content -> setObject(String::create("测试标题"), "title");
content -> setObject(String::create("测试描述"), "description");
content -> setObject(String::create("http://sharesdk.cn"), "url");
content -> setObject(String::createWithFormat("%d", C2DXContentTypeWebPage), "type");
content -> setObject(String::create("http://sharesdk.cn"), "siteUrl");
content -> setObject(String::create("ShareSDK"), "site");
content -> setObject(String::create("http://mp3.mwap8.com/destdir/Music/2009/20090601/ZuiXuanMinZuFeng20090601119.mp3"), "musicUrl");
content -> setObject(String::create("extInfo"), "extInfo");

Dictionary可用的Key如下,如果需要用到其它字段,可自行参考Sample中的代码实现: (并不是所有平台都有这些字段,需要参考文档 Android_不同平台分享内容的详细说明)

 Key  描述
 text/content  要分享的内容,注意在文档中content对应的是text字段
 description  内容简要,评论
 image  要分享的图片,可以是本地路径imagePath(如:/sdcard/a.jpg)或是一个网址imageUrl
 title  要分享的标题
 titleUrl  QQ和QQ空间分享的网页链接
 url  网页分享,仅需要图文分享时,不要传这个字段
 type  内容类型,具体参考enum C2DXContentType
 site  内容来源的站点名称
 siteUrl  内容来源的站点链接
 musicUrl  音乐分享,音乐文件的网址
 extInfo  微信分享应用时传给应用的附加信息,参考微信API文档

然后将内容传入分享接口:

<strong>两种分享形式</strong>
//显示分享菜单(九宫格)
C2DXShareSDK::showShareMenu(NULL, content, 100, 100, shareContentResultHandler);

//单独平台分享(以微博为例)
C2DXShareSDK::shareContent(cn::sharesdk::C2DXPlatTypeSinaWeibo, content, shareContentResultHandler);

其中shareContentResultHandler为回调方法,其定义如下:

//分享回调
void shareContentResultHandler(int seqId, cn::sharesdk::C2DXResponseState state, cn::sharesdk::C2DXPlatType platType, __Dictionary *result)
{
    switch (state)
    {
        case cn::sharesdk::C2DXResponseStateSuccess:
        {
            log("Success");
        }
            break;
        case cn::sharesdk::C2DXResponseStateFail:
        {
            log("Fail");
            //回调错误信息
            __Array *allKeys = result->allKeys();
            allKeys->retain();
            for (int i = 0; i < allKeys-> count(); i++)
            {
                __String *key = (__String*)allKeys->getObjectAtIndex(i);
                Ref *obj = result->objectForKey(key->getCString());

                log("key = %s", key -> getCString());
                if (dynamic_cast<__String *>(obj))
                {
                    log("value = %s", dynamic_cast<__String *>(obj) -> getCString());
                }
                else if (dynamic_cast<__Integer *>(obj))
                {
                    log("value = %d", dynamic_cast<__Integer *>(obj) -> getValue());
                }
                else if (dynamic_cast<__Double *>(obj))
                {
                    log("value = %f", dynamic_cast<__Double *>(obj) -> getValue());
                }
            }
        }
            break;
        case cn::sharesdk::C2DXResponseStateCancel:
        {
            log("Cancel");
        }
            break;
        default:
            break;
    }
}

 

 

1.4、用户授权

调用C2DXShareSDK中的authorize方法可进行用户授权。代码如下:

C2DXShareSDK::authorize(C2DXPlatTypeSinaWeibo, authResultHandler);

其中authResultHandler为回调方法,其定义如下:

//授权回调
//获取用户信息结果回调
void getUserResultHandler(int reqID, C2DXResponseState state, C2DXPlatType platType, __Dictionary *result)
{
    switch (state)
    {
        case cn::sharesdk::C2DXResponseStateSuccess:
        {
            log("Success");
            if (result == NULL) {
 				break;
			}
            //输出信息
            try
            {
                __Array *allKeys = result -> allKeys();
                allKeys->retain();
                for (int i = 0; i < allKeys -> count(); i++)
                {
                    __String *key = (__String *)allKeys -> getObjectAtIndex(i);
                    Ref *obj = result -> objectForKey(key -> getCString());

                    log("key = %s", key -> getCString());
                    if (dynamic_cast<__String *>(obj))
                    {
                        log("value = %s", dynamic_cast<__String *>(obj) -> getCString());
                    }
                    else if (dynamic_cast<__Integer *>(obj))
                    {
                        log("value = %d", dynamic_cast<__Integer *>(obj) -> getValue());
                    }
                    else if (dynamic_cast<__Double *>(obj))
                    {
                        log("value = %f", dynamic_cast<__Double *>(obj) -> getValue());
                    }
                }
                allKeys->release();
            }
            catch(...)
            {
                log("==============error");
            }
        }
            break;
        case cn::sharesdk::C2DXResponseStateFail:
        {
            log("Fail");
            //回调错误信息
			if (result == NULL) {
 				break;
			}
            __Array *allKeys = result->allKeys();
            allKeys->retain();
            for (int i = 0; i < allKeys-> count(); i++)
            {
                __String *key = (__String*)allKeys->getObjectAtIndex(i);
                Ref *obj = result->objectForKey(key->getCString());

                log("key = %s", key -> getCString());
                if (dynamic_cast<__String *>(obj))
                {
                    log("value = %s", dynamic_cast<__String *>(obj) -> getCString());
                }
                else if (dynamic_cast<__Integer *>(obj))
                {
                    log("value = %d", dynamic_cast<__Integer *>(obj) -> getValue());
                }
                else if (dynamic_cast<__Double *>(obj))
                {
                    log("value = %f", dynamic_cast<__Double *>(obj) -> getValue());
                }
            }
        }
            break;
        case cn::sharesdk::C2DXResponseStateCancel:
        {
            log("Cancel");
        }
            break;
        default:
            break;
    }
}

 

1.5、获取用户资料

调用C2DXShareSDK中的getUserInfo方法可获取授权用户信息。代码如下:

C2DXShareSDK::getUserInfo(C2DXPlatTypeSinaWeibo, getUserResultHandler);

其中getUserResultHandler为回调方法,其定义如下:

//获取用户信息结果回调
void getUserResultHandler(int reqID, C2DXResponseState state, C2DXPlatType platType, __Dictionary *result)
{
    switch (state)
    {
        case cn::sharesdk::C2DXResponseStateSuccess:
        {
            log("Success");
            if (result == NULL) {
 				break;
			}
            //输出信息
            try
            {
                __Array *allKeys = result -> allKeys();
                allKeys->retain();
                for (int i = 0; i < allKeys -> count(); i++)
                {
                    __String *key = (__String *)allKeys -> getObjectAtIndex(i);
                    Ref *obj = result -> objectForKey(key -> getCString());

                    log("key = %s", key -> getCString());
                    if (dynamic_cast<__String *>(obj))
                    {
                        log("value = %s", dynamic_cast<__String *>(obj) -> getCString());
                    }
                    else if (dynamic_cast<__Integer *>(obj))
                    {
                        log("value = %d", dynamic_cast<__Integer *>(obj) -> getValue());
                    }
                    else if (dynamic_cast<__Double *>(obj))
                    {
                        log("value = %f", dynamic_cast<__Double *>(obj) -> getValue());
                    }
                }
                allKeys->release();
            }
            catch(...)
            {
                log("==============error");
            }
        }
            break;
        case cn::sharesdk::C2DXResponseStateFail:
        {
            log("Fail");
            //回调错误信息
			if (result == NULL) {
 				break;
			}
            __Array *allKeys = result->allKeys();
            allKeys->retain();
            for (int i = 0; i < allKeys-> count(); i++)
            {
                __String *key = (__String*)allKeys->getObjectAtIndex(i);
                Ref *obj = result->objectForKey(key->getCString());

                log("key = %s", key -> getCString());
                if (dynamic_cast<__String *>(obj))
                {
                    log("value = %s", dynamic_cast<__String *>(obj) -> getCString());
                }
                else if (dynamic_cast<__Integer *>(obj))
                {
                    log("value = %d", dynamic_cast<__Integer *>(obj) -> getValue());
                }
                else if (dynamic_cast<__Double *>(obj))
                {
                    log("value = %f", dynamic_cast<__Double *>(obj) -> getValue());
                }
            }
        }
            break;
        case cn::sharesdk::C2DXResponseStateCancel:
        {
            log("Cancel");
        }
            break;
        default:
            break;
    }
}

 

 

(不集成Android分享可略过此部分)
注意:
本节介绍的是结合Jni将Share SDK集成到coco2d-x的方式,如果您想查询“纯Java方式”的集成方法,请点击这里参考“Android 示例项目”条目的相关内容,如果您想查询“plugin-x”的集成方法,请点击这里参考“Android 示例项目”条目的相关内容。

集成步骤

集成到你的cocos2dx里要做的是
1:把ShareSDK的cocos2dx的sample项目里的libs架包复制到你的项目里,除了armeabi目录不用复制其他都要。
2:把ShareSDK的cocos2dx的sample项目里的Classes目录下的文件都复制到你的项目里的Classes目录下。
3:把ShareSDK的cocos2dx的sample项目里的res里的drawable-xhdpi和values目录下的oks_string.xml、ssdk_string.xml复制到你的项目里的res目录下,values-en是国际化需要用到的
4:把ShareSDK的cocos2dx的sample项目里的AndroidManifest.xml里的<activity android:name=”com.mob.tools.MobUIShell” />的属性和<user-permission>都复制到你的项目里的AndroidManifes.xml里,如果需要集成微信分享还需要设置微信的回调activity,具体如何写可以查阅 Android_快速集成指南 的配置AndroidManifes.xml节点。
5:添加代码把ShareSDKUtils.java一定要放在cn.sharesdk目录下,onekeyshare是做快捷分享,onekeyshare也在cn.sharesdk下创建变成cn.sharesdk.onekeyshare,然后把onekeyshare代码复制到你的项目里
6:在主activity里的onCreate方法里添加ShareSDKUtils.prepare()方法。
7:在jni/Android.mk添加下面代码来引入相关文件,如:

LOCAL_SRC_FILES := hellocpp/main.cpp \

../../Classes/AppDelegate.cpp \
   ../../Classes/HelloWorldScene.cpp \
   ../../Classes/C2DXShareSDK/Android/ShareSDKUtils.cpp \
   ../../Classes/C2DXShareSDK/C2DXShareSDK.cpp \
   ../../Classes/C2DXShareSDK/Android/JSON/CCJSONConverter.cpp \
   ../../Classes/C2DXShareSDK/Android/JSON/cJSON/cJSON.c

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \

$(LOCAL_PATH)/../../Classes/C2DXShareSDK \
   $(LOCAL_PATH)/../../Classes/C2DXShareSDK/Android \
   $(LOCAL_PATH)/../../Classes/C2DXShareSDK/Android/JSON \
   $(LOCAL_PATH)/../../Classes/C2DXShareSDK/Android/JSON/cJSON

8、在项目属性页选择C/C++ builder,在build command处填入python ${ProjDirPath}/build_native.py -b release (注意需要安装python,ndk要使用r9或者更高版本)cocos2d-x C++ (Android)集成第三方微信分享

9、添加一些环境变量

cocos2d-x C++ (Android)集成第三方微信分享

添加COCOS2DX_ROOT,也就是cocos2dx解压缩的根目录
如果你没有设置系统变量NDK_ROOT,那么要添加系统变量或在这里添加NDK_ROOT,也就是NDK解压缩的根目录
如果你没有设置系统变量,那么要添加系统变量或在这里添加ANDROID_SDK_ROOT,也就是Android SDK的根目录

10、设置一下资源的环境变量

cocos2d-x C++ (Android)集成第三方微信分享

在这个页面点击Link Source…按钮

cocos2d-x C++ (Android)集成第三方微信分享

路径指向COCOS2DX根目录\cocos\platform\android\java\src,Folder name: libcocos2d或其它不存在的名称

11、最后尝试执行项目,点击分享正常显示此图就表明集成ShareSDK C2DX成功了,恭喜你

cocos2d-x C++ (Android)集成第三方微信分享

  • ShareSDK.xml配置文件说明

里面配置的信息是你的应用到各个分享平台注册你的应用时所返回的注册信息,把项目的注册信息填写到ShareSDK.xml
详细的JAVA代码说明和配置信息说明请查阅Android快速集成指南

此demo不能执行分享功能,因为没有到各个分享平台里注册此应用信息,所以要你的应用到各个分享平台里注册应用信息后把相关的注册信息填写到ShareSDK.xml就能执行分享了,祝你顺利。

分享过程中出现异常请查阅常见问题板块

3.2 java层代码解释

java层代码基本上只有ShareSDKUtils一个类,而且java层的代码也仅仅需要调用这个类的prepare方法,此外的可以不理会。但是如果您想修改分享的参数(github上的例子提供的分享参数很少),则需要涉及下面的方法:

 nativeMapToJavaMap(HashMap<String, String>)
 这个方法是将从native层传递上来的分享数据的名称修改为java层可以理解的名称,如果您在native层添加了分享的参数,则需要修改这个方法,将这些参数“翻译”为Java层可以理解的字段,
 这些字段实际上就是不同平台ShareParams的字段,完整列表,可以参考这里
 onekeyShare(HashMap<String, String>)
 这个方法是调用java层快捷分享GUI模块的入口,和上面的方法一样,如果您修改了native层的分享参数,这个方法里面的方法也需要增删。

需要特别注意的是,ShareSDKUtils.prepare()必须在主线程中调用,而且需要在触发Share SDK的任何操作前触发,否则会因为没有初始化ShareSDKUtils而导致错误。

3.3 native层代码解释

直接使用jni的方式集成Share SDK并不是Android平台所推荐的做法,实践证明,这种方式需要涉及大量的native-java反射操作,低效且容易发生错误,但是这种方法可以在编写c/c++代码时屏蔽平台差异,也可以当作是对Plugin-x的补充。
native层的代码基本上是反射操作,开发者可以完全不理会其实现,直接调用C2DXShareSDK上的方法完成需要的功能即可,如果需要修改其中的功能,可以到ShareSDKUtils中改动,但是需要注意下面的方法:

 Java_cn_sharesdk_Cocos2dPlatformActionListener_onCancel
 Java_cn_sharesdk_Cocos2dPlatformActionListener_onComplete
 Java_cn_sharesdk_Cocos2dPlatformActionListener_onError
 这三个方法是java层的操作回调,不应该修改方法的名称
 hashmapToCCDictionary及其引用的方法
 这个方法的用途主要是将包含操作返回的json容器hashmap转成ccdictionary
 CCDictionaryToHashMap
 这个方法是hashmapToCCDictionary的逆操作,但事实上这个方法只能转换key和value都是string的数据