融雲——佳信客服,集成小記

前段時間,做了個佳信客服的對接。在這裏做個記錄。
資源地址:
SDK下載路徑:
https://www.rongcloud.cn/downloads
接入融雲–佳信客服
https://www.rongcloud.cn/docs/customer_service.html#jiaxin
文檔:
https://www.rongcloud.cn/docs/android_imlib.html#客服
融雲獲取token
https://www.rongcloud.cn/docs/server.html#user_get_token
融雲–佳信客服–客服管理:
https://developer.rongcloud.cn/CustomerJiaXin/base/Kal0xrpnVB4nQWrIKoA=
佳信客服–後臺管理–坐席管理:
https://dev2.kefucloud.net/#
客服對話工作臺:
https://agent2.kefucloud.net/
android 問題 解決方案:官方:
https://support.rongcloud.cn/ks/NjIz

集成:
首先下載SDK分爲兩種IMKit和IMLib
IMKit包含融雲的UI頁面,IMLib只有相應的庫資源,需自己定製UI頁面。
我這裏直接使用了融雲的UI頁面
一、將IMKit以module的形式依賴到項目中

在這裏插入圖片描述
因爲IMKit中依賴了IMLib所以,將兩個module都導入到項目中

2、在app下的buile.gradle中添加依賴與配置
1)dependencies 裏面加入IMKit的依賴

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
  	...
    api project(path: ':IMKit')
}

2)在lib文件夾下添加依賴的jar包與so文件
這裏爲了簡便,直接copy官方demo的lib
在這裏插入圖片描述
同時由於IMKit整體代碼數量較多,需要在
android {

}
中加入一些配置,用於指定libs路徑與防止65536的情況,:


    sourceSets {
        main {
            jni.srcDirs = []
            jniLibs.srcDirs = ['libs']
        }
    }
    dexOptions {
        incremental true
        javaMaxHeapSize "4g"
    }

這時同步一下環境就集成好了。

3、在IMLib的AndroidManifest.xml文件中填入自己再融雲官網申請的APPKEY
在這裏插入圖片描述
因爲融雲的頁面都是通過intent,Uri來進行調整的。
所以我們需要在AndroidManifest中指明對應的 intent-filter
這裏以直接打開客服的對話頁面爲例:
在Manifest中配置如下:
在這裏插入圖片描述
host裏的值爲自己應用的包名
pathPrefix裏面的 “/conversation/”是會話頁面的標記
在這個Activity對應的xml佈局文件中,通過Fragment導入融雲的客服頁面。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <fragment
        android:id="@+id/conversation"
        android:name="io.rong.imkit.fragment.ConversationFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

接下來要正式進行打開融雲客服頁面的操作了:
一、融雲SDK初始化
在應用Application的onCreate方法中執行

RongIM.init(this);

完成SDK的初始化

二、放一個按鈕,用於點擊操作打開客服對話頁面
點擊按鈕:
在點擊事件裏面,通過下面的方法打開融雲的會話頁面。:
在頁面跳轉前,需要確保融雲服務已經連接,
通過文檔,我們知道每個用戶對應一個融雲的roken,那個怎麼獲取這個token呢?
由於這個項目沒有後臺人員對接融雲客服,所以只能自己來獲取token了。

直接上代碼了:

獲取融雲token:

	/**
     * 獲取融雲的 token
     * @param userId 用戶ID
     * @return 包含融雲token的json字符串
     */
    public static String getRongCloudToken(String userId, String nickName) {
        StringBuffer res = new StringBuffer();
        String url = HttpInterface.GET_RONG_TOKEN;
        String App_Key = Constant.RongCloud.APP_KEY; //開發者平臺分配的 App Key。
        String App_Secret = Constant.RongCloud.APP_SECRET;
        String Timestamp = String.valueOf(System.currentTimeMillis() / 1000);//時間戳,從 1970 年 1 月 1 日 0 點 0 分 0 秒開始到現在的秒數。
        String Nonce = String.valueOf(Math.floor(Math.random() * 1000000));//隨機數,無長度限制。
        String Signature = sha1(App_Secret + Nonce + Timestamp);//數據簽名。
        Log.i(TAG, "獲取到的融雲數據簽名:" + Signature);
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("App-Key", App_Key);
        httpPost.setHeader("Timestamp", Timestamp);
        httpPost.setHeader("Nonce", Nonce);
        httpPost.setHeader("Signature", Signature);
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(1);
        nameValuePair.add(new BasicNameValuePair("userId", userId));
        HttpResponse httpResponse = null;
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair, "utf-8"));
            httpResponse = httpClient.execute(httpPost);
            BufferedReader br = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
            String line = null;
            while ((line = br.readLine()) != null) {
                res.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        Log.i(TAG, "獲取到融雲token:" + res.toString());
        return res.toString();
    }

    //SHA1加密//http://www.rongcloud.cn/docs/server.html#通用_API_接口簽名規則
    private static String sha1(String data) {
        StringBuffer buf = new StringBuffer();
        try {
            MessageDigest md = MessageDigest.getInstance("SHA1");
            md.update(data.getBytes());
            byte[] bits = md.digest();
            for (int i = 0; i < bits.length; i++) {
                int a = bits[i];
                if (a < 0)
                    a += 256;
                if (a < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(a));
            }
        } catch (Exception e) {

        }
        return buf.toString();
    }

這時候獲取到的融雲token是已json形式返回的,所以我們要對json字符串進行解析:
這裏使用的是Gson解析

				if (!TextUtils.isEmpty(rongJson)) {
                    RongCloudJsonData rongCloudJsonData = GsonUtils.parseJSON(rongJson, RongCloudJsonData.class);
                    if (null != rongCloudJsonData) {
                        String rongToken = rongCloudJsonData.getToken();
                        mInstance.setStringValue("rongToken", rongToken);
                        connectRongCloud(rongToken);
                    }
                }

上面這段代碼要進行融雲連接融雲服務的操作,所以要放到子線程中操作。

連接融雲客服:

	/**
     * 連接融雲客服
     * @param rongToken 融雲的token
     */
    private void connectRongCloud(String rongToken) {
        RongIM.connect(rongToken, new RongIMClient.ConnectCallback() {
            @Override
            public void onTokenIncorrect() {
                Log.i(TAG, "token錯誤");
            }

            @Override
            public void onSuccess(String s) {
                Log.i(TAG, "融雲連接成功");
            }

            @Override
            public void onError(RongIMClient.ErrorCode errorCode) {
                Log.i(TAG, "融雲連接錯誤");
            }
        });
    }

打開融合客服對話頁面:

RongIM.getInstance().startConversation(getContext(), Conversation.ConversationType.CUSTOMER_SERVICE, "service", "在線客服");

就可以打開我們在Manifest中配置的那個Activity了。
其中:“service”是客服後臺裏面,坐席管理–技能組ID裏的值。如下圖
在這裏插入圖片描述

這時候運行你的項目,如果在logcat中看到了三個進程,那說明集成沒有問題,可以繼續了。
在這裏插入圖片描述
打開APP,點擊按鈕,跳轉到客服頁面。
在這裏插入圖片描述
這時候就可以愉快的和客服聊天了。

=================================================================

是不是覺得這就結束了,並沒有。。。。
下面說說遇到的問題:

1、這樣集成以後,當你發送消息的時候,客服後臺是看不到你的暱稱的
通過文檔得知,融雲是通過Provider來獲取和保存用戶的信息的,這些信息都被保存到數據庫中了,因此我們需要通過Provider把我們的用戶信息,存到數據庫中,讓融雲可以獲取到。
解決:
參照文檔:
通過先通過RongIM.setUserInfoProvider()設置用戶信息,
然後在做頁面的跳轉,操作。如下:

 		RongIM.setUserInfoProvider(this, true);
        RongIM.getInstance().setCurrentUserInfo(new io.rong.imlib.model.UserInfo(userId, nickName, Uri.parse(Constant.USER_ICON)));

        /**
         * <p>啓動會話界面。</p>
         * <p>使用時,可以傳入多種會話類型 {@link io.rong.imlib.model.Conversation.ConversationType} 對應不同的會話類型,開啓不同的會話界面。
         * 如果傳入的是 {@link io.rong.imlib.model.Conversation.ConversationType#CHATROOM},sdk 會默認調用
         * {@link RongIMClient#joinChatRoom(String, int, RongIMClient.OperationCallback)} 加入聊天室。
         * 如果你的邏輯是,只允許加入已存在的聊天室,請使用接口 {@link #startChatRoomChat(Context, String, boolean)} 並且第三個參數爲 true</p>
         * @param context          應用上下文。
         * @param conversationType 會話類型。
         * @param targetId         根據不同的 conversationType,可能是用戶 Id、羣組 Id 或聊天室 Id。
         * @param title            聊天的標題,開發者可以在聊天界面通過 intent.getData().getQueryParameter("title") 獲取該值, 再手動設置爲標題。
         */
        RongIM.getInstance().startConversation(getContext(), Conversation.ConversationType.CUSTOMER_SERVICE, "service", "在線客服");

然而這樣還是沒有用。看文檔發現,
在application的onCreate方法中的初始化代碼後面還要加一行代碼
設置發送消息攜帶用戶信息。

@Override
    public void onCreate() {
        super.onCreate();
        RongIM.init(this);
        /**
         * 設置消息體內是否攜帶用戶信息。
         * @param state 是否攜帶用戶信息,true 攜帶,false 不攜帶。
         */
        RongIM.getInstance().setMessageAttachedUserInfo(true);
    }

這樣在發送消息的時候,客服後臺就接收到了傳過來的用戶名了。

問題二:
進入客服對話頁面的時候,會有一個提示:
在這裏插入圖片描述
點擊“留言”按鈕,進入留言頁面
一個web頁面,發現居然是一片空白。。。

不明白是怎麼回事,於是諮詢融雲的客服
讓我在進入客服頁面的時候斷點獲取到:
“url”:“https://web.jiaxincloud.com/gray/jiaxin-phone.html?id=z3b4zmtvnhd0mq&appName=dpdyy091&appChannel=10001
webView加載的url地址也獲取到了,是正常的。可是webView卻沒有展示出來
最後是讓我自定義一個WebView來解決這個問題的
因爲這個頁面也是URI來實現的,所以我們自定義一個activity,在manifest中指定activity的
intent-filter
在IMKit的manifest中
這個就是容易的留言頁面,我們把intent-filter註釋掉,copy到我們自己的activity下。

		<activity
            android:name="io.rong.imkit.tools.RongWebviewActivity"
            android:exported="false"
            android:screenOrientation="portrait">
            <!--<intent-filter>-->
                <!--<action android:name="io.rong.imkit.intent.action.webview" />-->
                <!--<category android:name="android.intent.category.DEFAULT" />-->
            <!--</intent-filter>-->
        </activity>

自定義留言頁面中WebView的代碼如下:


   	 private void initWebView() {
        mWebView = findViewById(R.id.webView);
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setDomStorageEnabled(true);//主要是這句
        webSettings.setJavaScriptEnabled(true);//啓用js
        webSettings.setBlockNetworkImage(false);//解決圖片不顯示
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setLoadsImagesAutomatically(true);

        //        webSettings.setAppCacheEnabled(true);
        //        webSettings.setDomStorageEnabled(true);
        //        webSettings.supportMultipleWindows();
        //        webSettings.setAllowContentAccess(true);
        //        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        //        webSettings.setUseWideViewPort(true);
        //        webSettings.setLoadWithOverviewMode(true);
        //        webSettings.setSavePassword(true);
        //        webSettings.setSaveFormData(true);

        mWebView.setWebChromeClient(new WebChromeClient());//這行最好不要丟掉
        //該方法解決的問題是打開瀏覽器不調用系統瀏覽器,直接用webview打開
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });
        mWebView.loadUrl(webUrl);
    }

這樣就可以正常顯示留言的頁面了
在這裏插入圖片描述
接着把玩這個客服模塊
發送語音、圖片都沒問題。
然後拍照的時候,應用奔潰了

看到在Manifest.xml的最後有一段代碼
把他放到我們應用的Manifest中就解決問題了。

		<!-- 此部分代碼需要移植到您的 app 下的 manifest,並且 authorities 指定您的包名。例如:com.android.FileProvider -->
        <!-- 否則使用拍照功能時,會崩潰 -->
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.zxf.pawnfund.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/rc_file_path" />
        </provider>

後面還遇到了,發送表情圖片沒問題,但是接受客服發送過來的表情卻顯示符號的問題

諮詢客服後,說是web上的表情和手機上的表情是不一樣的,他們沒有做適配,如果要正常顯示,需要自己去自定義適配。。
這裏不再贅述。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章