写在前面:本人是个新手程序,很多问题可能都是我太菜导致的,这里只做个人记录。如果有大佬有更好的解决方案的话也希望能帮小弟我解惑。
可能是因为我没做 捕获异常的原因,但凡是初始化了 云信SDK后,只要因为Unity报错或者其他问题导致 程序无法正常退出的时候,Unity就会直接卡死。
SDK提供的接口都是异步接口,通过回调函数接收执行结果,在回调函数中不能直接操作UI对象,可以将结果保存起来在update函数中更新游戏,或者通过其他方式进行更新。(在demo中提供了Loom类实现这个功能。)
云信SDK的网络消息基类是 NIMIMMessage 类,其他类型的网络消息基本上都是 由它派生出来的,例如 NIMAudioMessage,NIMTextMessage,NIMImageMessage,NIMTipMessage 等等。然而消息接受的回调参数中返回来的是一个 NIMIMMessage 类型的对象。
// 消息接受的回调
public void OnMessageReceived( object sender, NIMReceiveMessageEventArgs args )
// 这是消息回调中,回调回来的参数 NIMReceiveMessageEventArgs 类的定义。
public class NIMReceiveMessageEventArgs : EventArgs
{
public NIMReceiveMessageEventArgs(NIMReceivedMessage msg)
{
Message = msg;
}
public NIMReceivedMessage Message { get; set; }
}
// 这是 NIMReceivedMessage 类的定义
public class NIMReceivedMessage : NimJsonObject<NIMReceivedMessage>
{
internal const string MessageContentPath = "content";
...
[JsonProperty(MessageContentPath)]
public NIMIMMessage MessageContent { get; set; }
...
// 安卓工程 manifests 权限
<!-- Enable internet for app!!!. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Getting the state of internet for app!!!. -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- write or read user data file for app!!!. -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.CAMERA" />
一开始打包成出安卓工程真机测试时,初始化SDK时报错,提示无法Create_path。然后换了一台测试机,发现可以正常初始化。然后就去查权限获取的问题。
正常来说 Unity 导出安卓工程后,工程中的 manifests.xml 中 作为应用程序启动入口的 Activity 应该是 Unity 生成的 UnityPlayerActivity,然而接入了云信SDK后的 导出的安卓工程中的 manifests 应该是修改了原本 Unity 生成的
// 以下是接入云信SDK后的安卓工程的 manifests.xml 中活动的声明
<activity
// 主要是 name 这里的区别
**android:name="com.netease.nimlib.MainActivity"**
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
android:hardwareAccelerated="false"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="fullSensor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<meta-data
android:name="unityplayer.UnityActivity"
android:value="true" />
<meta-data
android:name="unityplayer.ForwardNativeEventsToDalvik"
android:value="false" />
</activity>
<activity
android:name="com.netease.nimlib.MainActivity"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="fullSensor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="unityplayer.UnityActivity"
android:value="true" />
<meta-data
android:name="unityplayer.ForwardNativeEventsToDalvik"
android:value="false" />
</activity>
I/Unity: 音频信息:StopCapture rescode:200
file_path:/sdcard/com.netease.nim_unity_android_demo/NIM/audio/181366001.aac
file_ext:aac
上面这个是 录制完成后输入的部分音频信息。 file_path 是音频的路径。
//如果是发送本地文件,请给LocalFilePath赋值
msg.LocalFilePath="c:\\audio.aac";
而发送音频网络消息 需要文件绝对路径,如上图这种。具体原因猜测可能是 Unity识别不了 “/”这样的文件路径吧。
这个接口并没有在Unity集成的文档中提到,如果是第一次接入此SDK并且首先接Unity的话,很容易就不知道附件下载到哪里去了。
///
/// 从消息的中获取附件(图片、语音、视频等)的本地路径
///
/// 消息对象
/// 消息如果有附件,不管是否已下载,返回附件的本地路径;消息如果没有附件,返回空字符串""
public static string GetAttachmentPathFromMsg(NIMIMMessage msg)
{
var jsonMsg = msg.Serialize();
var ptr = TalkNativeMethods.nim_talk_get_attachment_path_from_msg(jsonMsg);
NimUtility.Utf8StringMarshaler marshaler = new NimUtility.Utf8StringMarshaler();
var path = marshaler.MarshalNativeToManaged(ptr) as string;
GlobalAPI.FreeBuffer(ptr);
return path;
}
聊天室的创建需要调用到云信服务端的API,云信服务器那边只接受 Http Post 请求,下载了云信提供的服务端API调用demo示例,发现C#的demo好像并没有写出如何在请求中添加参数,只有Java版本的。所以我用了我们项目引用的第三方工具——BestHttp,可以正常与云信服务器那边发送请求了。
未完,因为公司需要换一个即时通讯产品,所以此文章暂时告一段落了,如果以后有时间的话会再继续更新完善的。