亲加sdk是一个可以用来给应用,游戏接入聊天功能的sdk,稳定性不错,并且可以跨平台,比如cocos2d-x,所以在不同的平台上编码逻辑是一样的,不一样的只是配置。
我这里接入的是cocos2d-x的版本,在这里记录下几个需要注意的地方。
1.聊天消息记录
如果需要获取跟某个指定对象(好友/聊天室/群组)的聊天消息列表,可以使用以下接口:
const std::vector<GotyeMessage>*pMessageList = apiist-> getMessageList(target, true);
但是这个消息更准确的应该是聊天消息历史记录列表,这个列表只是在刚进入聊天室的时候会返回你不在聊天室时,聊天室的消息列表,而如果你已经进入聊天室,第二次调用的时候,比如你发完消息就调用,返回的是空的,只有你退出聊天室,重新进入的时候获取聊天消息列表才会获取到。
所以最好的办法就是本地保存一个相同的vector,当初次进入的时候更新本地的vector,然后自己发消息就只更新本地的vector,消息列表也读取本地的vector列表,
当有新消息到达,API会给出以下回调:
//详见GotyeDelegate.h virtual void onReceiveMessage(const GotyeMessage& message, bool* downloadMediaIfNeed)///<新接收的消息
在这里也仅仅更新自己本地的vector并且刷新列表即可。
2.发送者的信息
信息发送的时候可以调用如下接口发送
GotyeMessagemessage = GotyeMessage::createTextMessage(sender,receiver, “Hello”);
这里可以在发送的时候自定义sender,如果不自定义sender默认是自己,什么叫自定义sender呢,就是可以增加sender(发送者)的字段内容,但是需要注意的是在获取到对方消息的时候,message里面的那个sender的字段并不是获取的所有的,有的sender中的字段内容虽然设置了,但是获取的时候并没有全部获取所有字段的内容,必须要调用获取用户详情的接口才可以全部获得,否则即使发送的时候设置了,接受的时候依旧是空的,所以这里如果你不想调用这个接口,那么需要注意下哪个是在message里面获取的,那个是必须通过接口获取的,然后把东西放到不需要通过接口就可以得到的
在API消息数据类型中,发送者和接收者通常都是GotyeChatTarget类型,它是用户(GotyeUser),群(GotyeGroup)以及聊天室(GotyeRoom)的共同父类
GotyeUser user = apiist->getUserDetail (target,false);
3.注册账户和修改账户信息
如果选择的是开放注册,那么只要填写登录账号就会直接登录了,如果有这个账号,就会登录这个账号,如果没有这个账号就会创建一个这个账号,当创建账号的时候,他默认的昵称和帐号名是一样的,可以后面调用修改账户信息来修改昵称,从而以后可以通过判断昵称和账号是否一样来判断是不是新注册账号。但是需要注意一点,如果是新注册账号,最好延迟两三秒再调用修改账户信息的接口
apiist->reqModifyUserInfo(loginUser, & imagePath);///<对应异步回调GotyeDelegate:: onModifyUserInfo
因为在用的时候发现老账号没问题,但是一注册立马调用修改账户的接口会有延迟或者回调不及时的问题,延迟两秒调用没有出现此问题。
安卓专属
注意:亲加在说明文档中,都是说的在cocos2dxActivity中,其实意思应该不是强调的文件,而是类,因为工程继承的就是这个,所以初始化init的函数可以卸载自己的工程的类中。
1.sdk的初始化
亲加API要求在libcocos2dx工程的Cocos2dxActivity.java中加入初始化操作,而且初始化接口调用必须紧跟随动态库加载操作执行完成,onLoadNativeLibraries()函数实现如下,完成对cocos2dx动态库的加载:
protected void onLoadNativeLibraries() { try { ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA); Bundle bundle = ai.metaData; String libName = bundle.getString("android.app.lib_name"); System.loadLibrary("cocos2dcpp"); } catch (Exception e) { e.printStackTrace(); } }
紧随其后初始化亲加API,
注意:cocos2d-x版本不同,加载动态库的时机可能不尽一样,不管如何变化,只要保证在加载操作执行(System.loadLibrary)之后马上调用亲加API的初始化接口就OK(可在libcocos2dx工程搜索System.loadLibrary)。
这里一般只要搜索自己的工程中的System.loadLibrary即可,如果是使用他的方法,要注意他的那个写的library的名字是否和你用的那个名字一样
可以参考这个文章:UnsatisfiedLinkError: Couldn't load cocos2dcpp: findLibrary returned null
2.mainloop
驱动GotyeAPI(仅针对Android)
GotyeAPI通过接口mainLoop将异步回调通知到主线程,因此,GotyeAPI需要得到主线程驱动,具体方法是, 在cocos2d-x调度器CCScheduler.cpp的update函数里面,调用GotyeAPI::mainLoop函数:
#include “GotyeAPI.h” void Scheduler::update(float dt) { … apiist->mainLoop();/* api在主线程循环驱动下,将各类异步回调通知到调用层 */ }
但是如果你在调用亲加的功能时,工程里面并没有调用schedule的函数,那么这个主线程循环的函数是没有调用的。所以也就收不到消息,这个坑了我好久,最后是对方技术提供的方案,在自己的类中调用schedule,然后自己写一个函数,函数里面调用mainloop函数即可,目的就是为了回调。
ChatLayer::ChatLayer() { this->schedule(schedule_selector(ChatLayer::mymainloop)); apiist->setJVM(JniHelper::getJavaVM());///< 设置JVM apiist->addListener(*this); } ChatLayer::~ ChatLayer() { if (!apiist->isInRoom(m_pRoomID)) { //退出聊天室 GotyeRoom world(m_pRoomID); apiist->leaveRoom(world); } apiist->logout(); apiist->removeListener(*this); this->unschedule(schedule_selector(ChatLayer::mymainloop)); } ///设置mainloop void ChatLayer::mymainloop(float t) { apiist->mainLoop(); }
最后感谢亲加技术的热心帮助
亲加通信云官方地址:http://www.gotye.com.cn/
版权属于:东哥笔记 - DongGe.org
本文链接:https://dongge.org/blog/252.html
自2017年12月26日起,『转载以及大段采集进行后续编辑』须注明本文标题和链接!否则禁止所有转载和采集行为!