即时通讯(四)---初始化融云

1.获取Token

在这里插入图片描述

功能描述
生成用户在融云的唯一身份标识 Token,客户端在使用融云通讯能力前必须获取 Token,融云 SDK 每次连接服务器时,都需要向融云服务器提供 Token,以便验证身份。

每个用户在进入MainActivity时,都需要想融云请求Token,并连接上融云。

在这里插入图片描述
输入参数,我们使用Bmob注册的userId和userName, 因为返回的userId与输入的用户ld相同,这样我们在进行聊天的时候,可以直接传入对方在Bmob的用户Id,即可建立双方的连接

除了上面的输入参数外,向融云请求Token,还需要提供4个Http Request Header
在这里插入图片描述

数据签名的获取

我们可以通过 App-Key、Nonce、TimeStamp来进行获取,具体代码如下

 */
public class SHA1 {

    /**
     * 融云加密算法
     * @param data
     * @return
     */
    public 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){
            e.printStackTrace();
        }
        return buf.toString();
    }
}

封装请求Token类

接下来就可以向融云发送Http请求,获取Token,代码如下

public class HttpManager {
    //初始化 OkHttp
     private static OkHttpClient mOkHttpClient;
    //发送post请求的url
     private  static  String POST_URL = "http://api-cn.ronghub.com/user/getToken.json";
    //融云的App_key
    private  static  String APP_KEY = "c9kqb3rdc200j";

    //单例模式
    private  static    HttpManager instance = null;

    public HttpManager() {
        mOkHttpClient = new OkHttpClient();
    }

    public  static  HttpManager getInstance(){
        if(instance ==null){
            instance = new HttpManager();
        }
        return  instance;
    }

    //发送post请求 获取融云Token
    public   String postCloudToken(HashMap<String,String> hashMap){
        //随机数
        String nonce = String.valueOf(Math.floor(Math.random()*10000));
        //时间戳
        String timestamp = String.valueOf(System.currentTimeMillis()/1000);
        //数据签名
        String signature = SHA1.sha1("w4hvJUN1yUuA"+nonce+timestamp);

        //初始化要提交的表单
        FormBody.Builder builder = new FormBody.Builder();
        //循环叫hashmap用的键值对添加到要提交的表单中 
        for(String key:hashMap.keySet()){
            builder.add(key,hashMap.get(key));
        }
        RequestBody requestBody = builder.build();
        //发送post请求
        Request build = new Request.Builder()
                .url(POST_URL)
                .post(requestBody)
                .addHeader("App-Key", APP_KEY)
                .addHeader("Nonce", nonce)
                .addHeader("Timestamp", timestamp)
                .addHeader("Signature", signature)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();


        try {
            return  mOkHttpClient.newCall(build).execute().body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return  "";
    }
}

请求Token代码中的 HashMap保存的是用户Id、用户姓名、及用户头像,也就是请求Token需要传入的当前用户参数.

检查Token

获取Token之后,我们可以将Token保存在SharedPreferences里面去,每次在进入MainActivity的时候,先去检查SharedPreferences里面是否有Token,有Token就直接进行连接融云,没有就去请求融云获取Token,具体代码如下

public class SpUtils {
    public static SharedPreferences preferences;

    public  static  SharedPreferences getInstance(Context context){
        if(preferences==null){
            preferences = context.getSharedPreferences("app",Context.MODE_PRIVATE);
        }
        return  preferences;
    };
}


//检查TOKEN
        private void checkToken() {
                //获取TOKEN 需要三个参数 1.用户ID 2.头像地址 3.昵称
                String token = SpUtils.getInstance(this).getString(Constant.TOKEN,"");
                if(!TextUtils.isEmpty(token)){
                        //如果有token 就启动云服务去连接融云服务
                        startCloudServer();
                }else {
                        //1.有三个参数
                        String tokenPhoto = BmobManager.getInstance().getUser().getTokenPhoto();
                        String tokenNickName = BmobManager.getInstance().getUser().getTokenNickName();
                        if(!TextUtils.isEmpty(tokenPhoto) || !TextUtils.isEmpty(tokenNickName)){
                                //创建Token
                                creareToken();
                        }else{
                                //创建上传提示框
                                createUploadDialog();
                        }
                }
        }

BmobManager.getInstance().getUser()这个方法是获取当前的用户,我把关于Bmob的所有方法都写在BmobManager里面进行封装,前面的登录实现,已经对BmobManager进去了说明

请求Token

也就是creareToken()方法, 具体代码如下

   private void creareToken() {
               //创建获取token的数据 用户名 和name
                final HashMap<String, String> hashMap = new HashMap<>();
                hashMap.put("userId",BmobManager.getInstance().getUser().getObjectId());
                hashMap.put("name",BmobManager.getInstance().getUser().getNickName());
                //通过Okhttp请求Token
                disposable = Observable.create(new ObservableOnSubscribe<Object>() {
                        @Override
                        public void subscribe(ObservableEmitter<Object> observableEmitter) throws Exception {
                                //执行请求过程
                                String json = HttpManager.getInstance().postCloudToken(hashMap);
                                observableEmitter.onNext(json);
                                observableEmitter.onComplete();
                        }
                        //线程调度
                }).subscribeOn(Schedulers.newThread())
                        .subscribeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Consumer<Object>() {
                                @Override
                                public void accept(Object s) throws Exception {
                                        //通过gson获取融云Token
                                        getCloudToken((String)s);
                                }
                        });
        }

将Token保存到内部存储中

也就是 getCloudToken((String)s)方法,具体代码如下

		public class tokenben {
		    //"code":200,
		    // "userId":"b3aaba9b03",
		    // "token":"KPvSFGpeOPfXE0IFW6Ti6nm4WWPy2yyjXqGumVmbBI8=@yoha.cn.rongnav.com;yoha.cn.rongcfg.com"
		
		    private  int code;
		    private  String userId;
		    private  String token;
		}

        private void getCloudToken(String s) {
                Gson gson = new Gson();
                tokenben tokenben = gson.fromJson(s, new tokenben().getClass());
//                System.out.println("==============================="+tokenben);
                //将token存储到内部存储中
                SpUtils.getInstance(this).edit().putString(Constant.TOKEN,tokenben.getToken()).commit();
                //连接融云服务
                startCloudServer();
        }

连接融云

也就是startCloudServer()方法,具体代码如下

        private  void startCloudServer(){
                 //如果有token 就启动云服务去连接融云服务
                     startService(new Intent(this, CloudService.class));
      			}

这里我们使用Service去连接融云服务,因为通过startService()启动了服务,则服务是Started状态。一旦启动,服务可以在后台无限期运行,即使启动它的组件已经被销毁。 使用我们需要时刻去监听其它用户,发送过来的信息,所有需要使用Service。

CloudService介绍

在CloudService我们去连接融云,会去接收对方发送过来的聊天消息、音视频、添加好友消息、同意好友消息等等。因为Service在后台可以无限期运行,可以时时刻刻去监听.

在写CloudService代码之前,先来介绍一下CloudManager这个类,我把关于融云操作所有的方法封装在这个类中,方便我们进行管理

CloudManager代码如下

package com.example.meet.manager;

import android.content.Context;
import android.net.Uri;
import android.widget.Toast;

import com.example.meet.R;
import com.example.meet.bmob.BmobManager;
import com.example.meet.utils.LogUtils;

import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import io.rong.calllib.IRongCallListener;
import io.rong.calllib.IRongReceivedCallListener;
import io.rong.calllib.RongCallClient;
import io.rong.calllib.RongCallCommon;
import io.rong.imlib.IRongCallback;
import io.rong.imlib.RongIMClient;
import io.rong.imlib.model.Conversation;
import io.rong.imlib.model.Message;
import io.rong.message.ImageMessage;
import io.rong.message.LocationMessage;
import io.rong.message.TextMessage;

public class CloudManager {
    private  static  CloudManager instance = null;
    //发送post请求的url
    private  static  String POST_URL = "http://api-cn.ronghub.com/user/getToken.json";
    //融云的App_key
    private  static  String APP_KEY = "c9kqb3rdc200j";
    //融云的App_sercet
    private  static  String APP_SECRET = "w4hvJUN1yUuA";

    //ObjectName
    public static  final  String MSG_TEXT_NAME = "RC:TxtMsg";
    public static  final  String MSG_IMAGE_NAME = "RC:ImgMsg";
    public static  final  String MSG_LOCATION_NAME = "RC:LBSMsg";

    //普通信息
    public  static  final String TEXT_MESSAGE = "TEXT_MESSAGE";
    //添加好友的信息
    public  static  final String SEND_ADD_FRIEND = "SEND_ADD_FRIEND";
    //同意好友的信息
    public  static  final String SEND_AGREEN_FRIEND = "SEND_AGREEN_FRIEND";

    //来电铃声
    public static final String callAudioPath = "http://downsc.chinaz.net/Files/DownLoad/sound1/201501/5363.wav";
    //挂断铃声
    public static final String callAudioHangup = "http://downsc.chinaz.net/Files/DownLoad/sound1/201501/5351.wav";
    public CloudManager() {

    }

    public  static  CloudManager getInstance(){
        if(instance == null){
            instance = new CloudManager();
        }
        return  instance;
    }

    //初始化融云
    public  void initCloud(Context context){
        String app_key = "c9kqb3rdc200j";
        RongIMClient.init(context,app_key);
    }

    //连接融云
    public  void connectCloud(String token){
        RongIMClient.connect(token, new RongIMClient.ConnectCallback() {
            //token错误
            @Override
            public void onTokenIncorrect() {
                LogUtils.i("token错误");
            }

            //连接成功 userId 当前用户 ID
            @Override
            public void onSuccess(String userId) {
                LogUtils.i("userId"+userId);
                LogUtils.i("融云连接成功");
                //发送消息测试
//                CloudManager.getInstance().sendTextMessage("很高兴认识你","5c97e446e5");
            }

            //连接失败
            @Override
            public void onError(RongIMClient.ErrorCode errorCode) {
                LogUtils.i("errorCode"+errorCode);
            }
        });
    }

    // 在断开和融云的连接后,有新消息时,仍然能够收到推送通知,调用 disconnect() 方法。
    public  void disconnect(){
        RongIMClient.getInstance().disconnect();
    }

    //断开连接后,不想收到任何推送通知,调用 logout() 方法。
    public void  logout(){
        RongIMClient.getInstance().logout();
    }

    //接收消息的监听器
    public  void setOnReceiveMessageListener(RongIMClient.OnReceiveMessageListener listener){
        RongIMClient.setOnReceiveMessageListener( listener);
    }

    private  IRongCallback.ISendMessageCallback iSendMessageCallback = new IRongCallback.ISendMessageCallback() {
        @Override
        public void onAttached(Message message) {
            /**
             * 消息发送前回调, 回调时消息已存储数据库
             * @param message 已存库的消息体
             */
        }

        @Override
        public void onSuccess(Message message) {
            /**
             * 消息发送成功。
             * @param message 发送成功后的消息体
             */
            LogUtils.i("发送消息成功+Success");
        }

        @Override
        public void onError(Message message, RongIMClient.ErrorCode errorCode) {
            /**
             * 消息发送失败
             * @param message   发送失败的消息体
             * @param errorCode 具体的错误
             */
            LogUtils.i("发送消息失败+Error"+errorCode);
        }
    };

    //发生文本消息
    public  void sendTextMessage(String msg,String targetId){
        //构建文本消息实例
        TextMessage textMessage = TextMessage.obtain(msg);
        Message message = Message.obtain(targetId, Conversation.ConversationType.PRIVATE,textMessage);
        RongIMClient.getInstance().sendMessage(message,null,null,iSendMessageCallback);
    }

    //发送文本消息,但是发送的是一个Json
    public  void sendTextMessage(String msg,String type,String targetId){
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("msg",msg);
            jsonObject.put("type",type);
            jsonObject.put("targetId",targetId);
            jsonObject.put("sendId", BmobManager.getInstance().getUser().getObjectId());
            //开始发送信息
//            LogUtils.i("发送者的id为"+targetId);
            sendTextMessage(jsonObject.toString(),targetId);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //查询本地的会话记录
    public  void getConversationList(RongIMClient.ResultCallback<List<Conversation>> callback){
        RongIMClient.getInstance().getConversationList(callback);
    }

    //获取本地的历史消息记录
    public  void getHistoryMessages(String targetId, RongIMClient.ResultCallback<List<Message>> callback){
        RongIMClient.getInstance().getHistoryMessages(Conversation.ConversationType.PRIVATE,targetId,-1,1000,callback);
    }

    //获取服务器的历史消息记录 相当于换了一台手机跟别人聊天
    public  void getRemoteHistoryMessages(String targetId, RongIMClient.ResultCallback<List<Message>> callback){
        RongIMClient.getInstance().getRemoteHistoryMessages(Conversation.ConversationType.PRIVATE,targetId,0,1000,callback);
    }


    //发送图片消息
    public   void sendImageMessage(File file,String targetId, RongIMClient.SendImageMessageCallback callback){
        ImageMessage imageMessage = ImageMessage.obtain(Uri.fromFile(file), Uri.fromFile(file), true);
        RongIMClient.getInstance().sendImageMessage(Conversation.ConversationType.PRIVATE,targetId,imageMessage,
                null,null,callback);
    }

    //发送位置信息
    public void sendLocationMessage(double lat,double lng,String poi,String targetId, IRongCallback.ISendMessageCallback callback){
        LocationMessage locationMessage = LocationMessage.obtain(lat, lng, poi, null);
        Message message = Message.obtain(targetId, Conversation.ConversationType.PRIVATE, locationMessage);
        RongIMClient.getInstance().sendLocationMessage(message,null,null,callback);
    }

    //---------------------------Call API------------------------------------

    /**
     * 拨打视频/音频
     *
     * @param targetId
     * @param type
     */
    public void startCall(Context mContext, String targetId, RongCallCommon.CallMediaType type) {
        //检查设备可用
        if (!isVoIPEnabled(mContext)) {
            return;
        }
//        if(!isConnect()){
//            Toast.makeText(mContext, mContext.getString(R.string.text_server_status), Toast.LENGTH_SHORT).show();
//            return;
//        }
        List<String> userIds = new ArrayList<>();
        userIds.add(targetId);
        RongCallClient.getInstance().startCall(
                Conversation.ConversationType.PRIVATE,
                targetId,
                userIds,
                null,
                type,
                null);
    }

    /**
     * 音频
     *
     * @param targetId
     */
    public void startAudioCall(Context mContext, String targetId) {
        startCall(mContext, targetId, RongCallCommon.CallMediaType.AUDIO);
    }

    /**
     * 视频
     *
     * @param targetId
     */
    public void startVideoCall(Context mContext, String targetId) {
        startCall(mContext, targetId, RongCallCommon.CallMediaType.VIDEO);
    }

    /**
     * 监听音频通话
     *
     * @param listener
     */
    public void setReceivedCallListener(IRongReceivedCallListener listener) {
        if (null == listener) {
            return;
        }
        RongCallClient.setReceivedCallListener(listener);
    }

    /**
     * 接听
     *
     * @param callId
     */
    public void acceptCall(String callId) {
        LogUtils.i("acceptCall:" + callId);
        RongCallClient.getInstance().acceptCall(callId);
    }

    /**
     * 挂断
     *
     * @param callId
     */
    public void hangUpCall(String callId) {
        LogUtils.i("hangUpCall:" + callId);
        RongCallClient.getInstance().hangUpCall(callId);
    }

    /**
     * 切换媒体 视频转音频,音频转视频
     *
     * @param mediaType
     */
    public void changeCallMediaType(RongCallCommon.CallMediaType mediaType) {
        RongCallClient.getInstance().changeCallMediaType(mediaType);
    }

    /**
     * 切换摄像头
     */
    public void switchCamera() {
        RongCallClient.getInstance().switchCamera();
    }

    /**
     * 摄像头开关  是否关闭摄像头
     *
     * @param enabled
     */
    public void setEnableLocalVideo(boolean enabled) {
        RongCallClient.getInstance().setEnableLocalVideo(enabled);
    }

    /**
     * 音频开关 是否打开麦克风
     *
     * @param enabled
     */
    public void setEnableLocalAudio(boolean enabled) {
        RongCallClient.getInstance().setEnableLocalAudio(enabled);
    }

    /**
     * 免提开关
     *
     * @param enabled
     */
    public void setEnableSpeakerphone(boolean enabled) {
        RongCallClient.getInstance().setEnableSpeakerphone(enabled);
    }

    /**
     * 开启录音
     *
     * @param filePath
     */
    public void startAudioRecording(String filePath) {
        RongCallClient.getInstance().startAudioRecording(filePath);
    }

    /**
     * 关闭录音
     */
    public void stopAudioRecording() {
        RongCallClient.getInstance().stopAudioRecording();
    }

    /**
     * 监听通话状态
     *
     * @param listener
     */
    public void setVoIPCallListener(IRongCallListener listener) {
        if (listener == null) {
            return;
        }
        RongCallClient.getInstance().setVoIPCallListener(listener);
    }

    /**
     * 检查设备是否可用通话
     *
     * @param mContext
     */
    public boolean isVoIPEnabled(Context mContext) {
        if (!RongCallClient.getInstance().isVoIPEnabled(mContext)) {
            Toast.makeText(mContext, mContext.getString(R.string.text_devices_not_supper_audio), Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }
}

CloudManager这里的方法后面我们会一一介绍,先来看下CloudService里面的代码

public class CloudService extends Service implements View.OnClickListener {
 	@Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        initService();
        initWindow();
        //连接融云服务
        linkCloudServer();
    }
    private void linkCloudServer() {
        //获取Token
        String token = SpUtils.getInstance(this).getString(Constant.TOKEN,"");
        LogUtils.i("token"+token);
        //连接融云服务
        CloudManager.getInstance().connectCloud(token);
      }
 }

到此为此连接融云已经完成了,接下来就可以进行我们发送添加好友消息了,但是别忘记,我们需要自定义一个Application来初始化融云,初始化融云需要获取你在融云创建的应用的App_key,具体代码如下

public class  MyApplication  extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        //Bmob的初始化
        BmobManager.getInstance().initBmob(this);
        //初始化融云
        CloudManager.getInstance().initCloud(this);
        //初始化LitePal
        LitePal.initialize(this);
        //初始化窗口
        WindowHelper.getInstance().initWindow(this);
        //初始化ZXing
        ZXingLibrary.initDisplayOpinion(this);
    }
}

CloudManager里面的initCloud方法
 //初始化融云
    public  void initCloud(Context context){
        String app_key = "你的应用App_key";
        RongIMClient.init(context,app_key);
    }

需要注意的是 CloudService和MyApplication 需要在清单文件中注册,别忘记了哦!!!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值