注:最近项目需求要做语音聊天这一块的功能,想了几种方案,最后还是决定用第三方服务,毕竟日活50W以下亲加是免费的!
亲加官方给了一定的技术文档,但是遇到很多坑,我顺便都介绍一下
废话不多说,先介绍Android接入,下一章介绍iOS。
1.下载开发包
亲加开发包下载地址 http://www.gotye.com.cn/download.html
即时通讯云包含丰富的聊天功能接口,不用语音通讯云了,下这个开发包
Android开发的朋友们下android的包,android的接入官方文档很详细,而且相对比较容易,我试了一下按照文档做没什么问题,这里主要介绍unity接亲加sdk,unity开发一定要用这个插件,如果想在项目eclipse的sdk环境里面接android的开发包,然后出jar,再用unity出apk包会闪退,只能用unity导出eclipse工程,然后接android才能用,显然这样搞太麻烦了,不如直接用这个插件。
2.导入开发包
正常情况,我们项目都接了各种sdk,比如各种支付的sdk(如果没有,那很好,导入了直接用),如果有的话注意不要导入AndroidMainfest,不然会覆盖原来项目的配置文件
3.注册亲加账户,并添加相关功能
添加应用:
选开放注册比较方便,以后用户登录可以不要密码
创建完后会得到应用信息,得到的appkey开发中会用到
然后添加一些IM用户和聊天室用于测试
添加用户:
添加聊天室:
4.对接口,我演示一下对语音的接口,其他的也都类似,把这个文件随便拖到场景一个组件,appkey用注册成功福偶的key
这个示例要放在真机上跑,模拟器要报错。
using UnityEngine; using System.Collections; using gotye; public class MainManager : MonoBehaviour { public GotyeAPI api; string appKey = "xxxxxxxxxxxxxxxx"; string packageName = "com.gotye.api"; ListenerLogin listenerLogin; ListenerChat listenerChat; ListenerRoom listenerRoom; string resurt = ""; string text = ""; static MainManager _instance; public static MainManager Instance { get { return _instance; } } void Awake() { InvokeRepeating("mainLoop", 0.0f, 0.050f);//初始化 _instance = this; } // Use this for initialization void Start() { //初始化 api = GotyeAPI.GetInstance(); api.Init(appKey, packageName); //添加事件回调 listenerLogin = new ListenerLogin(); listenerChat = new ListenerChat(); listenerRoom = new ListenerRoom(); api.AddListener(listenerLogin); api.AddListener(listenerChat); api.AddListener(listenerRoom); } void OnGUI() { GUI.Label(new Rect(200, 0, 200, 200), text); GUI.Label(new Rect(200, 200, 200, 200), resurt); if (GUI.Button(new Rect(0, 0, 200, 100), "sq123登录")) { text = "sq123登录"; api.Login("sq123", null); } if (GUI.Button(new Rect(0, 100, 200, 100), "sq222登录")) { text = "sq222登录"; api.Login("sq222", null); } if (GUI.Button(new Rect(0, 200, 200, 100), "进入聊天室")) { //298926 text = "进入聊天室"; GotyeRoom room = new GotyeRoom(298926); api.EnterRoom(room); } if (GUI.Button(new Rect(0, 300, 200, 100), "开始说话")) { text = "开始说话"; GotyeRoom room = new GotyeRoom(298926); //api.SendMessage(GotyeMessage.CreateTextMessage(room, "111")); api.StartTalk(room,0,false,20000); } if (GUI.Button(new Rect(0, 400, 200, 100), "停止说话")) { text = "停止说话"; api.StopTalk(); } if (GUI.Button(new Rect(0, 500, 200, 100), "退出聊天室")) { text = "退出聊天室"; GotyeRoom room = new GotyeRoom(298926); api.LeaveRoom(room); } if (GUI.Button(new Rect(0, 600, 200, 100), "退出登录")) { text = "退出登录"; api.Logout(); } } void mainLoop()//初始化 { GotyeAPI.GetInstance().MainLoop(); } //显示Gui信息 public void ShowAnimate(string log) { text = log; } public void ShowResurt(string log) { resurt = log; } }
事件监听回调要继承开发包提供的接口,并且要以public的形式实现接口中所有的函数
ListenerChat:聊天回调
using UnityEngine; using System.Collections; using gotye; using System.Text; using System.Collections.Generic; public class ListenerChat : ChatListener { /** * 发送消息后回调 * @param code 状态码 参见 {@link GotyeStatusCode} * @param message 被发送的消息对象 */ public void onSendMessage(GotyeStatusCode code, GotyeMessage message) { MainManager.Instance.ShowResurt("发送消息: code = " + code.ToString()); } /** * 接收信息 * @param code 状态码 参见 {@link GotyeStatusCode} * @param message */ public void onReceiveMessage(GotyeMessage message) { if(message.Type == GotyeMessageType.Text) { MainManager.Instance.ShowResurt("接收文字信息"); } else if (message.Type == GotyeMessageType.Audio) { MainManager.Instance.ShowResurt("接收语音信息"); MainManager.Instance.api.DownloadMediaInMessage(message); } else { MainManager.Instance.ShowResurt("接收其他信息"); } } /** * 下载消息 * @param code 状态码 参见 {@link GotyeStatusCode} * @param message 下载的消息对象 */ public void onDownloadMediaInMessage(GotyeStatusCode code, GotyeMessage message) { MainManager.Instance.api.PlayMessage(message); } /** * 举报回调 * @param code 状态码 参见 {@link GotyeStatusCode} * @param message 被举报的消息 */ public void onReport(GotyeStatusCode code, GotyeMessage message) { } /** * 开始录制语音消息回调 * @param code 状态码 参见 {@link GotyeStatusCode} * @param isRealTime 是否实时语音 * @param targetType 发送对象类型 * @param target 发送对象 */ public void onStartTalk(GotyeStatusCode code, GotyeChatTarget target, bool isRealTime) { MainManager.Instance.ShowResurt("开始录制"); } /** * 停止录制语音消息回调 * @param code 状态码 参见 {@link GotyeStatusCode} * @param message * @param isVoiceReal */ public void onStopTalk(GotyeStatusCode code, bool realtime, GotyeMessage message/*, bool *cancelSending*/) { MainManager.Instance.ShowResurt("录制完成"); GotyeRoom room = new GotyeRoom(298926); MainManager.Instance.api.SendMessage(message); } /** * 解码语音消息 * @param code 状态码 参见 {@link GotyeStatusCode} * @param message 被解码的消息对象 */ public void onDecodeMessage(GotyeStatusCode code, GotyeMessage message) { } /** * 获取历史消息回调 * @deprecated * @param code 状态码 参见 {@link GotyeStatusCode} * @param list 历史消息列表 */ public void onGetMessageList(GotyeStatusCode code, List<GotyeMessage> list/*, bool downloadMediaIfNeed*/) { } public void onRequestCS(GotyeStatusCode code, GotyeUser user) { } /** * 设置群组消息回调 * @deprecated * @param code 状态码 参见 {@link GotyeStatusCode} * @param group 当前群组 * @param msgConfig 群组的消息配置参数 */ public void onSetGroupMsgConfig(GotyeStatusCode code, GotyeGroup group, GotyeGroupMsgConfig msgConfig) { } /** * 获取群组消息设置回调 * @deprecated * @param code 状态码 参见 {@link GotyeStatusCode} * @param group 当前的群组 */ public void onGetGroupMsgConfig(GotyeStatusCode code, GotyeGroup group, GotyeGroupMsgConfig msgConfig) { } /** * 获取离线消息回调 * @deprecated * @param code 状态码 参见 {@link GotyeStatusCode} * @param msgList 历史消息列表 * @param downloadMediaIfNeed 是否需要下载多媒体 */ public void onGetOfflineMessageList(GotyeStatusCode code, List<GotyeMessage> msgList/*, bool downloadMediaIfNeed*/) { } /** * 获取历史消息回调 * @deprecated * @param code 状态码 参见 {@link GotyeStatusCode} * @param list 历史消息列表 */ public void onGetHistoryMessageList(GotyeStatusCode code, List<GotyeMessage> msgList/*, bool downloadMediaIfNeed*/) { } /** * * @deprecated * @param code 状态码 参见 {@link GotyeStatusCode} */ public void onStartAPNS(GotyeStatusCode code) { } /** * * @deprecated * @param code 状态码 参见 {@link GotyeStatusCode} */ public void onStopAPNS(GotyeStatusCode code) { } /** * 更新未读消息回调 * @deprecated * @param code 状态码 参见 {@link GotyeStatusCode} */ public void onUpdateUnreadMessageCount(GotyeStatusCode code) { } public void onGetLastMessage(GotyeChatTarget target, GotyeMessage message) { } public void onGetSessionList(List<GotyeChatTarget> list) { } public void onGetUnreadMessageCount(GotyeChatTarget target, int count) { } public void onGetTotalUnreadMessageCount(int count) { } public void onGetTotalUnreadMessageCountOfTypes(List<GotyeChatTargetType> types, int count) { } }
ListenerLogin:登录回调
using UnityEngine; using System.Collections; using gotye; public class ListenerLogin : LoginListener { public void onLogin(GotyeStatusCode code, GotyeUser user) { MainManager.Instance.ShowResurt("用户登录:" + user.Name + " code = " + code.ToString()); } public void onLogout(GotyeStatusCode code) { MainManager.Instance.ShowResurt("用户登出:code = " + code.ToString()); } public void onReconnecting(GotyeStatusCode code, GotyeUser currentUser) { MainManager.Instance.ShowResurt("用户重新连接:code = " + code.ToString() + " id = " + currentUser.Name); } }
ListenerRoom:聊天室回调
using UnityEngine; using System.Collections; using System.Collections.Generic; using gotye; public class ListenerRoom : RoomListener { /** * 进入聊天室回调 * @param code 状态码 参见 {@link GotyeStatusCode} * @param room 当前聊天室对象 */ public void onEnterRoom(GotyeStatusCode code, GotyeRoom room) { MainManager.Instance.ShowResurt("进入房间 code = " + code.ToString() + " roomID = " + room.ID); } /** * 离开聊天室 * @param code 状态码 参见 {@link GotyeStatusCode} * @param room 当前聊天室对象 */ public void onLeaveRoom(GotyeStatusCode code, GotyeRoom room) { MainManager.Instance.ShowResurt("离开房间 code = " + code.ToString() + " roomID = " + room.ID); } /** * 回去聊天室列表 * @param code 状态码 参见 {@link GotyeStatusCode} * @param gotyeroom 聊天室列表 */ public void onGetRoomList(GotyeStatusCode code, int pageIndex, List<GotyeRoom> curPageRoomList, List<GotyeRoom> allRoomList) { } /** * 获取聊天室成员列表 * @param code 状态码 参见 {@link GotyeStatusCode} * @param room 当前聊天室 * @param totalMembers 每页结果集合 * @param currentPageMembers 当前页集合 * @param pageIndex 当前页码 */ public void onGetRoomMemberList(GotyeStatusCode code, GotyeRoom room, int pageIndex, List<GotyeUser> currentPageMembers, List<GotyeUser> totalMembers) { } public void onGetLocalRoomList(List<GotyeRoom> curPageRoomList) { } public void onGetRoomDetail(GotyeStatusCode code, GotyeRoom room) { } public void onGetRoomStatus(GotyeRoom room, bool In) { } public void onGetRoomRealtimeStatus(GotyeRoom room, bool support) { } }
这几个文件都导入后,用unity导出eclipse工程,把导出的项目src下的三个unity文件删掉,然后把原来项目主jar包删掉
然后把项目sdk环境合并进来,在启动Activity的onCreate()中初始化亲加的api,添加这一行就可以了:
GotyeAPI.getInstance().init(getApplicationContext(), "6e6c4968-b491-4fbf-8ff1-68b06ee134ee", GotyeAPI.SCENE_UNITY3D);
运行,还有会报一些文件的错误,比如resource.ap_,都删掉,直到能在手机上跑起来,然后用俩手机对话一下,语音能互相收到,大部分内容就完成啦。
做到这一步,包已经可以出了,但是为了方便,还是用unity出包比较好,不然给次都导eclipse工程会会让人崩溃的!
5.导出jar包,用unity出apk
用这个项目导出一个主jar包,覆盖原来的,再用unity出apk
再次说一下这个大坑:
不要用亲加Android开发包添加到unity的sdk环境中出jar包,然后用unity出包。报找不到文件内容的错,这是个大坑!
在eclipse中新建项目导入开发环境测试运行没问题,总觉得是个包是OK的,但导入到unity就崩溃,哪位大侠知道这是什么原因还望告知。