1. 程式人生 > >Android 網易雲IM開發

Android 網易雲IM開發

  • 點對點聊天

即一對一單聊,網易雲信 SDK 提供文字、圖片、語音、地理位置、檔案、自定義訊息等多種能力,開發者可根據自身需求定製附件下載、未讀、推送等多種訊息行為。

  • 群聊天

即多人聊天群組服務,內建普通群和高階群,普通群類似於沒有許可權的討論組,適用於快速建立多人會話的場景;高階群在普通群的基礎上擁有了更多的許可權設定,包括邀請的驗證方式,管理員許可權,禁言等更高階的功能,適用於更復雜更定製化的場景。

群聊天有人數限制,人數在千級別以上推薦使用聊天室。

  • 聊天室聊天

聊天室是群聊人數在萬級甚至更多的聊天解決方案,可用於遊戲直播,網路授課,遠端醫療等業務場景上。聊天室沒有人數限制,同時提供基本的許可權服務。

聊天室在進入時需要重新建立連結,同時由於場景訊息量通常很大, SDK 不會做聊天室訊息儲存,需要上層自行實現。 在人數低於千級別時,推薦使用群組聊天。

  • 訊息全文檢索

網易雲通訊 Android SDK 擁有基於 Lucene 的全文檢索外掛,支援聊天訊息的全文檢索。

  • 資料託管

網易雲通訊提供了使用者資料的可選託管,開發者可以根據喜好,將使用者資料託管給網易雲信或者 APP 應用伺服器自行管理。

  • 訊息推送

整合網易雲通訊 Android SDK 的 APP 執行起來時,會有個後臺程序(push 程序),該程序保持了與網易雲通訊 Server 的長連線。只要這個 push 程序活著(網易雲通訊提供安卓保活機制),就能接收網易雲通訊 Server 推過來的訊息,進行通知欄提醒。

  • 事件訂閱

網易雲信允許使用者訂閱監聽其他使用者產生的事件,產生的事件的方式分為兩種:

1. 使用者主動釋出的自定義事件。

2. 由於使用者的一些特定行為觸發的內建系統事件。

開發者可以用事件訂閱自定義使用者的線上狀態,如忙碌,隱身等等。

  • 高清語音

網易雲信提供了音訊播放、高清語音錄製的功能。格式支援 aac 和 amr。

  • 智慧對話機器人

智慧對話機器人解決方案依託網易即時通訊、語音識別、語義理解等服務,為開發者提供人機互動 API / SDK、語音識別、意圖識別、知識庫配置、動態介面等功能,可以在應用內快速整合場景豐富的智慧對話機器人。

大概功能就是這些。。。

網易雲官方也提供了快速整合Im功能庫。

SDK 4.4.0 API呼叫框架增強:

  • 支援帶 Looper 的非UI執行緒發起的非同步API呼叫,直接回調到呼叫者執行緒。老版本會預設回撥到 UI 執行緒。
  • 提供非同步強制轉成同步的介面:NIMClient#syncRequest,允許設定最大同步等待時間,支援非 UI 執行緒裡需要同步呼叫雲信 API的場景。
  • 新增自動生成的 NIMSDK類,開發者可以直接採用 NIMSDK#getXXXService 方法獲取服務介面,不再需要傳遞 XXXService.class,簡化 API 呼叫方式。其他外掛自動生成的呼叫入口類為:NIMChatRoomSDK、NIMLuceneSDK。例如採用 NIMSDK.getAuthService().login() 替換NIMClient.getService(AuthService.class).login()

 文件首頁 IM 音視訊通話 簡訊 直播 點播 互動直播 互動白板 

 登入 註冊

IM即時通訊

  • 通過 Gradle 整合 SDK

  • 通過類庫配置整合 SDK

  • 許可權與元件

  • 混淆配置

  • 總體介面介紹

  • SDK 資料快取目錄結構

  • 整合方式

整合方式

IM SDK 是網易雲通訊其他能力(實時語音視訊、互動白板等)的基礎,本節講述 IM SDK 的整合步驟也將其他能力 SDK 的整合步驟融合起來,開發者可以根據實際業務需要選擇接入的類庫。

網易雲通訊 IM SDK 支援兩種方式整合。

1. 通過 Gradle 整合 SDK (推薦)

2. 通過類庫配置整合 SDK

網易雲通訊 Android SDK 2.5.0 以上強烈推薦通過 Gradle 整合 SDK。

注意: 1. IM SDK 最低要求 Android 4.0, 其中網路音視訊通話和白板最低要求 Android 4.1。

2. 從 3.2 版本開始 jni 庫支援 64位 系統

此外,為了讓開發者可以輕鬆快速的在 App 中整合 IM 功能,我們還提供了開源的 聊天元件,通過簡單的配置就可以實現聊天功能。

通過 Gradle 整合 SDK

首先,在整個工程的 build.gradle 檔案中,配置 repositories,使用 jcenter 或者 maven ,二選一即可,如下:

複製allprojects {
    repositories {
        jcenter() // 或者 mavenCentral()
    }
}

第二步,在主工程的 build.gradle 檔案中,新增 dependencies。根據自己專案的需求,新增不同的依賴即可。注意:版本號必須一致,這裡以 5.6.1 版本為例:

複製
android {
   defaultConfig {
       ndk {
           //設定支援的SO庫架構
           abiFilters "armeabi-v7a", "x86","arm64-v8a","x86_64"
        }
   }
}

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    // 新增依賴。注意,版本號必須一致。
    // 基礎功能 (必需)
    implementation 'com.netease.nimlib:basesdk:5.6.1'
    // 音視訊和互動白板服務需要
    implementation 'com.netease.nimlib:nrtc:5.6.1'
    // 音視訊需要
    implementation 'com.netease.nimlib:avchat:5.6.1'
    // 聊天室需要
    implementation 'com.netease.nimlib:chatroom:5.6.1'
    // 互動白板服務需要
    implementation 'com.netease.nimlib:rts:5.6.1'
    // 全文檢索服務需要
    implementation 'com.netease.nimlib:lucene:5.6.1'
    // 小米、華為、魅族、fcm 推送
    implementation 'com.netease.nimlib:push:5.6.1'
}

再次注意:依賴包的版本號必須一致。

通過類庫配置整合 SDK

首先到下載頁面進行下載 Android SDK。開發者可以根據實際需求,配置類庫。

以下介紹以 Android SDK v2.5 及以上版本為例,Android SDK v2.5 以下的配置,請諮詢技術支援。

網易雲通訊 Android SDK v2.5 及以上分為兩種 SDK 包下載,第一種包含全部功能:IM + 聊天室 + 推送 + 實時音視訊 + 教學白板。第二種包含部分功能,包含:IM + 聊天室 + 推送。

SDK 包的 libs 資料夾中,包含了網易雲通訊的 jar 檔案,各 jni 庫資料夾以及 SDK 依賴的第三方庫。

第一種,包含全部功能的 SDK 包。如果需用網易雲通訊 SDK 提供的所有功能,將這些檔案拷貝到你的工程的 libs 目錄下,即可完成配置。列表如下:

複製libs
├── arm64-v8a
│   ├── libne_audio.so (高清語音錄製功能必須)
│   ├── libnrtc_engine.so (音視訊需要)
│   └── libnrtc_network.so (音視訊需要)
│   └── librts_network.so (實時會話服務需要)
├── armeabi-v7a
│   ├── libne_audio.so
│   ├── libnrtc_engine.so
│   └── libnrtc_network.so
│   └── librts_network.so
├── x86
│   ├── libne_audio.so
│   ├── libnrtc_engine.so
│   └── libnrtc_network.so
│   └── librts_network.so
├── x86_64
│   ├── libne_audio.so
│   ├── libnrtc_engine.so
│   └── libnrtc_network.so
│   └── librts_network.so
│
├── nim-basesdk-5.6.1.jar (基礎功能)
├── nim-chatroom-5.6.1.jar (聊天室需要)
├── nim-rts-5.6.1.jar (互動白板、文件轉碼需要)
├── nim-avchat-5.6.1.jar (音視訊需要)
├── nim-lucene-5.6.1.jar (全文檢索需要)
├── nim-push-5.6.1.jar(推送需要)
├── nrtc-sdk.jar(音視訊需要)

第二種,只包含 IM 基礎功能和聊天室功能的 SDK 包。如果只需要 IM 基礎功能和聊天室功能,只需要將下面這些檔案拷貝到你的工程的 libs 目錄下,即可完成配置。列表如下:

複製libs
├── arm64-v8a
│   ├── libne_audio.so (高清語音錄製功能必須)
├── armeabi-v7a
│   ├── libne_audio.so
├── x86_64
│   ├── libne_audio.so
├── x86
│   ├── libne_audio.so
├── nim-basesdk-5.6.1.jar (基礎功能)
├── nim-push-5.6.1.jar (推送需要)
├── nim-chatroom-5.6.1.jar (聊天室需要)

以上檔案列表中,jar 檔案版本號可能會不同,子目錄中的檔案是 SDK 所依賴的各個 CPU 架構的 so 庫。

按需配置 jar 包: 如果不需要聊天室功能,可以在IM和聊天室的基礎包中,去掉 nim-chatroom-5.6.1.jar。 如果只需要 IM 基礎功能和 音視訊功能,可以在 IM 和聊天室的基礎包中,去掉 nim-chatroom-5.6.1.jar,so 庫需要加上 libnrtc*.so,還需加上 nim-avchat-5.6.1.jar 和 nrtc-sdk.jar。 如果不需要全文檢索功能,可以去掉 nim-lucene-5.6.1.jar(該包有 1M+ 大小,如果沒有用到訊息全文檢索功能,建議去掉)。

如果你使用的 IDE 是 Android Studio,要將 jni 庫按照 IDEA 工程目錄的結構,放置在對應的目錄中(一般為 src/main/jniLibs)。或者在 build.gradle 中配置好 jniLibs 的 sourceSets(可參考 demo 的 build.gradle)。

許可權與元件

在 AndroidManifest.xml 中加入以下配置:

複製<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="xxx">

    <!-- 許可權宣告 -->
    <!-- 訪問網路狀態-->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!-- 控制呼吸燈,振動器等,用於新訊息提醒 -->
    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <!-- 外接儲存存取許可權 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <!-- 多媒體相關 -->
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <!-- 如果需要實時音視訊通話模組,下面的許可權也是必須的。否則,可以不加 -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
     <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-feature android:glEsVersion="0x00020000" android:required="true" />

    <!-- SDK 許可權申明, 第三方 APP 接入時,請將 com.netease.nim.demo 替換為自己的包名 -->
    <!-- 和下面的 uses-permission 一起加入到你的 AndroidManifest 檔案中。 -->
    <permission
        android:name="com.netease.nim.demo.permission.RECEIVE_MSG"
        android:protectionLevel="signature"/>
    <!-- 接收 SDK 訊息廣播許可權, 第三方 APP 接入時,請將 com.netease.nim.demo 替換為自己的包名 -->
     <uses-permission android:name="com.netease.nim.demo.permission.RECEIVE_MSG"/>

    <application
        ...>
        <!-- APP key, 可以在這裡設定,也可以在 SDKOptions 中提供。
            如果 SDKOptions 中提供了,取 SDKOptions 中的值。 -->
        <meta-data
            android:name="com.netease.nim.appKey"
            android:value="key_of_your_app" />

        <!-- 雲信後臺服務,請使用獨立程序。 -->
        <service
            android:name="com.netease.nimlib.service.NimService"
            android:process=":core"/>

       <!-- 雲信後臺輔助服務 -->
        <service
            android:name="com.netease.nimlib.service.NimService$Aux"
            android:process=":core"/>

        <!-- 雲信後臺輔助服務 -->
        <service
            android:name="com.netease.nimlib.job.NIMJobService"
            android:exported="true"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:process=":core"/>

        <!-- 雲信監視系統啟動和網路變化的廣播接收器,保持和 NimService 同一程序 -->
        <receiver android:name="com.netease.nimlib.service.NimReceiver"
            android:process=":core"
            android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
            </intent-filter>
        </receiver>

        <!-- 雲信程序間通訊 Receiver -->
        <receiver android:name="com.netease.nimlib.service.ResponseReceiver"/>

        <!-- 雲信程序間通訊service -->
        <service android:name="com.netease.nimlib.service.ResponseService"/>

        <!-- 雲信程序間通訊provider -->
        <!-- android:authorities="{包名}.ipc.provider", 請將com.netease.nim.demo替換為自己的包名 -->
        <provider
            android:name="com.netease.nimlib.ipc.NIMContentProvider"
            android:authorities="com.netease.nim.demo.ipc.provider"
            android:exported="false"
            android:process=":core" />
    </application>
</manifest>

混淆配置

如果你的 apk 最終會經過程式碼混淆,請在 proguard 配置檔案中加入以下程式碼:

複製-dontwarn com.netease.**
-keep class com.netease.** {*;}
#如果你使用全文檢索外掛,需要加入
-dontwarn org.apache.lucene.**
-keep class org.apache.lucene.** {*;}

總體介面介紹

網易雲通訊 SDK 提供了兩類介面供開發者呼叫:一類是第三方 APP 主動發起請求,第二類是第三方 APP 作為觀察者監聽事件和變化。第一類介面名均以 Service 結尾,例如 AuthService ,第二類介面名均以 ServiceObserver 結尾,例如 AuthServiceObserver,個別太長的類名則可能直接以 Observer 結尾,比如 SystemMessageObserver。

SDK 提供三種介面返回值:基本資料型別(同步介面),InvocationFuture(非同步介面) 和 AbortableFuture(非同步介面)。非同步介面基本上都是從主程序發起呼叫,然後在後臺程序執行,最後再將結果返回給主程序。

SDK 介面返回值 說明
基本資料型別 同步介面
InvocationFuture 非同步介面
AbortableFuture 非同步介面,耗時很長或者傳輸大量資料時使用,可用 abort() 方法,中斷請求。 例如上傳下載、登入等

非同步介面可設定回撥函式,提供兩種方式:RequestCallback 和 RequestCallbackWrapper。

非同步介面回撥函式 說明
RequestCallback 需要實現3個介面: 成功 onSuccess, 失敗 onFailed, 異常 onException
RequestCallbackWrapper 需要實現 onResult。封裝了成功,失敗和異常的3個介面,在引數上進行區分

SDK 4.4.0 API呼叫框架增強:

  • 支援帶 Looper 的非UI執行緒發起的非同步API呼叫,直接回調到呼叫者執行緒。老版本會預設回撥到 UI 執行緒。
  • 提供非同步強制轉成同步的介面:NIMClient#syncRequest,允許設定最大同步等待時間,支援非 UI 執行緒裡需要同步呼叫雲信 API的場景。
  • 新增自動生成的 NIMSDK類,開發者可以直接採用 NIMSDK#getXXXService 方法獲取服務介面,不再需要傳遞 XXXService.class,簡化 API 呼叫方式。其他外掛自動生成的呼叫入口類為:NIMChatRoomSDK、NIMLuceneSDK。例如採用 NIMSDK.getAuthService().login() 替換NIMClient.getService(AuthService.class).login()

SDK 提供的介面主要按照業務進行分類,大致說明如下:

SDK介面 說明
AuthService 使用者認證服務介面,提供登入登出介面。
AuthServiceObserver 使用者認證服務觀察者介面。
MsgService 訊息服務介面,用於傳送訊息,管理訊息記錄等。 同時還提供了傳送自定義通知的介面。
MsgServiceObserve 接收訊息,訊息狀態變化等觀察者介面。
LuceneService 聊天訊息全文檢索介面。
TeamService 群組服務介面,用於傳送群組訊息,管理群組和群成員資料等。
TeamServiceObserve 群組和群成員資料變化觀察者。
SystemMessageService 系統通知觀察者。
FriendService 好友關係託管介面,目前支援新增、刪除好友、 獲取好友列表、黑名單、設定訊息提醒。
FriendServiceObserve 好友關係變更、黑名單變更通知觀察者。
UserService 使用者資料託管介面,提供獲取使用者資料、修改個人資料等。
UserServiceObserve 使用者資料託管介面,提供獲取使用者資料、修改個人資料等。
AVChatManager 語音視訊通話介面。
RTSManager 實時會話介面。
NosService 網易雲端儲存服務,提供檔案上傳和下載。
NosServiceObserve 網易雲端儲存傳輸進度觀察者介面。
MixPushService 第三方推送介面,提供第三方推送服務。
EventSubscribeService 事件訂閱服務介面,提供事件訂閱等服務
EventSubscribeServiceObserver 事件狀態變更觀察者介面。
RedPacketService 紅包介面。提供獲取紅包sdk token等功能。
RobotService 機器人操作相關介面,提供獲取機器人、 獲取機器人資訊、判斷是否是機器人等功能。
RobotServiceObserve 機器人資料變更觀察者介面。
SettingsService 系統設定介面。提供多端推送、免打擾配置
SettingsServiceObserver 系統設定變更觀察者介面。

接下來就是寫了一個demo

先註冊弄了兩個 賬號:777777 ,888888

package com.twc.wangyiyunzhibor;

import android.app.Application;

import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.auth.LoginInfo;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.util.NIMUtil;
import com.twc.wangyiyunzhibor.mymessage.CustomAttachParser;
import com.twc.wangyiyunzhibor.mymessage.GuessAttachment;
import com.twc.wangyiyunzhibor.mymessage.guest.MsgViewHolderGuess;
import com.twc.wangyiyunzhibor.register.IMListener;

/**
 * 賬號1 :777777
 * token 777777
 * <p>
 * 賬號2 :888888
 * token 888888
 */
public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        NIMClient.init(this, null, null);

        if (NIMUtil.isMainProcess(this)) {
            //判斷是否在主執行緒。
            IMListener.getInstance().init(this);
            // 初始化
            NimUIKit.init(this);
//
//            // 可選定製項
//            // 註冊定位資訊提供者類(可選),如果需要傳送地理位置訊息,必須提供。
//            // demo中使用高德地圖實現了該提供者,開發者可以根據自身需求,選用高德,百度,google等任意第三方地圖和定位SDK。
//            NimUIKit.setLocationProvider(new NimDemoLocationProvider());
//
//            // 會話視窗的定製: 示例程式碼可詳見demo原始碼中的SessionHelper類。
//            // 1.註冊自定義訊息附件解析器(可選)
//            // 2.註冊各種擴充套件訊息型別的顯示ViewHolder(可選)
//            // 3.設定會話中點選事件響應處理(一般需要)
//            SessionHelper.init();
//
//            // 通訊錄列表定製:示例程式碼可詳見demo原始碼中的ContactHelper類。
//            // 1.定製通訊錄列表中點選事響應處理(一般需要,UIKit 提供預設實現為點選進入聊天介面)
//            ContactHelper.init();
//
//            // 線上狀態定製初始化。
//            NimUIKit.setOnlineStateContentProvider(new DemoOnlineStateContentProvider());
            NIMClient.getService(MsgService.class).registerCustomAttachmentParser(new CustomAttachParser());
            NimUIKit.registerMsgItemViewHolder(GuessAttachment.class, MsgViewHolderGuess.class);
        }
    }

    private LoginInfo getLoginInfo() {
        return new LoginInfo("777777", "777777");
    }

}
package com.twc.wangyiyunzhibor;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.common.activity.UI;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.auth.AuthService;
import com.netease.nimlib.sdk.auth.LoginInfo;
import com.netease.nimlib.sdk.chatroom.ChatRoomService;
import com.netease.nimlib.sdk.chatroom.model.EnterChatRoomData;
import com.netease.nimlib.sdk.chatroom.model.EnterChatRoomResultData;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.team.TeamService;
import com.netease.nimlib.sdk.team.constant.TeamFieldEnum;
import com.netease.nimlib.sdk.team.constant.TeamTypeEnum;
import com.netease.nimlib.sdk.team.constant.VerifyTypeEnum;
import com.netease.nimlib.sdk.team.model.CreateTeamResult;
import com.twc.wangyiyunzhibor.bean.MsgEvent;
import com.twc.wangyiyunzhibor.mymessage.GuessAttachment;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * 網易雲賬號。
 * 賬號1 :777777
 * token 777777
 * <p>
 * 賬號2 :888888
 * token 888888
 */
public class MainActivity extends UI {

    @BindView(R.id.button)
    Button button;
    @BindView(R.id.button2)
    Button button2;
    @BindView(R.id.button3)
    Button button3;
    @BindView(R.id.textmsg)
    TextView textmsg;
    @BindView(R.id.button4)
    Button button4;
    @BindView(R.id.button5)
    Button button5;
    @BindView(R.id.button6)
    Button button6;
    @BindView(R.id.button7)
    Button button7;
    @BindView(R.id.button8)
    Button button8;
    @BindView(R.id.button9)
    Button button9;
    private Context context;

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void MsgEvent(MsgEvent event) {
        if (event != null) {
            textmsg.setText("實時情況:" + event.getMsg());
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    String groupId = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        EventBus.getDefault().register(this);
        context = this;
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                NIMClient.getService(AuthService.class).login(new LoginInfo("777777", "777777"))
                        .setCallback(new RequestCallback() {
                            @Override
                            public void onSuccess(Object param) {
                                Log.e("twc", param.toString());
                                NimUIKit.loginSuccess("777777");
                                Toast.makeText(MainActivity.this, "登入成功", Toast.LENGTH_LONG).show();
                            }

                            @Override
                            public void onFailed(int code) {
                                Log.e("twc", code + "---");
                            }

                            @Override
                            public void onException(Throwable exception) {
                                Log.e("twc", exception.toString());
                            }
                        });

            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                NIMClient.getService(AuthService.class).logout();
            }
        });
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // 該帳號為示例,請先註冊
                String account = "888888";
                // 以單聊型別為例
                SessionTypeEnum sessionType = SessionTypeEnum.P2P;
                String text = "this is an example";
                // 建立一個文字訊息
                IMMessage textMessage = MessageBuilder.createTextMessage(account, sessionType, text);
                // 傳送給對方  如果是傳送失敗後重發,標記為true,否則填false
                NIMClient.getService(MsgService.class).sendMessage(textMessage, false);

            }
        });
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 開啟單聊介面
                NimUIKit.startP2PSession(MainActivity.this, "888888", null);
//                P2PMessageActivity.start(MainActivity.this, "888888", "888888", "888888");
            }
        });
        button5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });

        button6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                fields - 群組預設資料, key為資料欄位,value對對應的值,該值型別必須和field中定義的fieldType一致。
//                type - 要建立的群組型別
//                postscript - 邀請入群的附言。如果是建立臨時群,該引數無效
//                members - 邀請加入的成員帳號列表
                List<String> sd = new ArrayList<String>();
                sd.add("777777");
                sd.add("888888");
                HashMap<TeamFieldEnum, Serializable> fields = new HashMap<TeamFieldEnum, Serializable>();
                fields.put(TeamFieldEnum.Name, "測試群");
//                VerifyType:申請入群的驗證方式
//                InviteMode 群邀請模式:誰可以邀請他人入群
                fields.put(TeamFieldEnum.VerifyType, VerifyTypeEnum.Free);
                NIMClient.getService(TeamService.class)
                        //  TeamTypeEnum  Normal(0), 普通群
                        //    Advanced(1);高階群
                        .createTeam(fields, TeamTypeEnum.Normal, "", sd)
                        .setCallback(new RequestCallback<CreateTeamResult>() {
                            @Override
                            public void onSuccess(CreateTeamResult createTeamResult) {
                                Log.e("result", "成功建立群組" + createTeamResult.toString());
                                groupId = createTeamResult.getTeam().getId();
                                Log.e("result", "成功建立群組id" + createTeamResult.getTeam().getId());
                            }

                            @Override
                            public void onFailed(int i) {
                                Log.e("result", i + "");
                            }

                            @Override
                            public void onException(Throwable throwable) {
                                Log.e("result", throwable + "");
                            }
                        });


            }
        });
        button7.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 開啟群聊介面
                NimUIKit.startTeamSession(context, groupId);
            }
        });
        button8.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // roomId 表示聊天室ID
                EnterChatRoomData data = new EnterChatRoomData("ooo111");
// 以登入一次不重試為例
                NIMClient.getService(ChatRoomService.class).enterChatRoomEx(data, 1).setCallback(new RequestCallback<EnterChatRoomResultData>() {
                    @Override
                    public void onSuccess(EnterChatRoomResultData result) {
                        Log.e("result", result + "登陸聊天室成功");
                        // 登入成功
                    }

                    @Override
                    public void onFailed(int code) {
                        Log.e("result", code + "登陸聊天室失敗");
                        // 登入失敗
                    }

                    @Override
                    public void onException(Throwable exception) {
                        // 錯誤
                        Log.e("result", exception + "登陸聊天室失敗");
                    }
                });
            }
        });
        button9.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                GuessAttachment attachment = new GuessAttachment();
                IMMessage message = MessageBuilder.createCustomMessage("888888", SessionTypeEnum.P2P,
                        attachment.getValue().getDesc(), attachment);
                NIMClient.getService(MsgService.class).sendMessage(message, false);
                NimUIKit.startP2PSession(MainActivity.this, "888888", null);
            }
        });
    }
}