====== 快速使用MQTT Android版 SDK实现消息收发 ====== 本文介绍Android端如何连接环信MQTT消息云快速实现消息的自收自发。 =====1. 前提条件===== ==== 1.1 部署Android开发环境 ==== 下载安装Android studio,配置好开发环境。 ==== 1.2 导入项目依赖 ==== 在项目根目录build.gradle文件里配置 \\ repositories { maven { url "https://repo.eclipse.org/content/repositories/paho-snapshots/" } } 另需要在app的build.gradle里添加依赖 dependencies { implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0' implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1' } ===== 2. 实现流程 ===== ==== 2.1 获取初始化信息 ==== 登录console后台 \\ 1.点击菜单栏【MQTT】->【服务概览】->【服务配置】,获取「连接地址」、「连接端口」、「AppID」以「及REST API地址」等信息。 \\ 注:clientID由两部分组成,组织形式为“deviceID@AppID”,deviceID由用户自定义,AppID见【服务配置】。 \\ 示例:正确的clientID格式为:“device001@aitbj0”; \\ 2.点击菜单栏【应用概览】->【应用详情】->【开发者ID】,获取「Client ID」与「ClientSecret」信息。 \\ 3.初始化代码 String host = "xxx.xxx.xxx.xxx"; //环信MQTT服务器地址 通过console后台[MQTT]->[服务概览]->[服务配置]下[连接地址]获取 String port="xx" // 协议服务端口 通过console后台[MQTT]->[服务概览]->[服务配置]下[连接端口]获取 String appId="xx"; // appID 通过console后台[MQTT]->[服务概览]->[服务配置]下[AppID]获取 String deviceId = "deviceId"; // 自定义deviceID String restApi = "xxx.xxx.xxx.xxx"; //环信MQTT REST API地址 通过console后台[MQTT]->[服务概览]->[服务配置]下[REST API地址]获取 String appClientId = "xxx"; //开发者ID 通过console后台[应用概览]->[应用详情]->[开发者ID]下[ Client ID]获取 String appClientSecret = "xxx"; // 开发者密钥 通过console后台[应用概览]->[应用详情]->[开发者ID]下[ ClientSecret]获取 String clientId = deviceId + "@" + appId; String userName = "test"; //自定义用户名 长度不超过64位即可 {{:playground:message:setting.jpg|}} {{:playground:message:develop.jpg|}} ==== 2.2 获取token ==== * 首先获取App Token try { JSONObject reqBody = new JSONObject(); reqBody.put("appClientId", appClientId); reqBody.put("appClientSecret", appClientSecret); OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody requestBody = RequestBody.create(mediaType, reqBody.toString()); Request request = new Request.Builder() .url(restApi + "/openapi/rm/app/token") .post(requestBody) .build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { String responseBody = response.body().string(); if (response.code() == 200 && !responseBody.isEmpty()) { try { JSONObject result = new JSONObject(responseBody); String appToken = result.optJSONObject("body").optString("access_token"); } catch (JSONException e) { e.printStackTrace(); } } } }); }catch (JSONException e){ e.printStackTrace(); } * 然后根据App Token获取User Token,User Token作为连接服务的密码 try { JSONObject reqBody = new JSONObject(); reqBody.put("username", userName); reqBody.put("expires_in", 86400);//过期时间,单位为秒,默认为3天,如需调整,可提工单调整 reqBody.put("cid", clientId); OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody requestBody = RequestBody.create(mediaType, reqBody.toString()); Request request = new Request.Builder() .url(restApi + "/openapi/rm/user/token") .addHeader("Authorization", appToken) .post(requestBody) .build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { String responseBody = response.body().string(); if (response.code() == 200 && !responseBody.isEmpty()) { try { JSONObject result = new JSONObject(responseBody); String userToken = result.optJSONObject("body").optString("access_token"); } catch (JSONException e) { e.printStackTrace(); } } } }); }catch (JSONException e){ e.printStackTrace(); } ==== 2.3 连接服务器 ==== 创建MqttAndroidClient对象,并配置连接密码、cleansession标志、心跳间隔、超时时间等信息,调用connect()函数连接至环信MQTT消息云。 MqttAndroidClient mMqttClient = new MqttAndroidClient(context, String.format("tcp://%s:%s", host, port), clientId); //连接参数 MqttConnectOptions options; options = new MqttConnectOptions(); //设置自动重连 options.setAutomaticReconnect(true); // 缓存 options.setCleanSession(true); // 设置超时时间,单位:秒 options.setConnectionTimeout(60); // 心跳包发送间隔,单位:秒 options.setKeepAliveInterval(45); // 用户名 options.setUserName(userName); // 密码 options.setPassword(userToken.toCharArray()); options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1); //进行连接 mMqttClient.connect(options, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { } ==== 2.4 订阅(subscribe) ==== 2.4.1 订阅主题 \\ 当客户端成功连接环信MQTT消息云后,需尽快向服务器发送订阅主题消息。 try { //连接成功后订阅主题 mMqttClient.subscribe(topic, qos, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { } }); } catch (MqttException e) { e.printStackTrace(); } 2.4.2 取消订阅 \\ try { mMqttClient.unsubscribe(topic); } catch (MqttException e) { e.printStackTrace(); } ==== 2.5 收发消息 ==== 2.5.1 发送消息 \\ 配置发送消息回调方法,向环信MQTT消息云中指定topic发送消息。 MqttMessage msg=new MqttMessage(); msg.setPayload(content.getBytes());//设置消息内容 msg.setQos(qos);//设置消息发送质量,可为0,1,2. //设置消息的topic,并发送。 mMqttClient.publish(topic, msg, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { Log.d(TAG, "onSuccess: 发送成功"); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { Log.d(TAG, "onFailure: 发送失败="+ exception.getMessage()); } }); 2.5.2 接收消息 \\ 配置接收消息回调方法,从环信MQTT消息云接收订阅消息。 // 设置MQTT监听 mMqttClient.setCallback(new MqttCallback() { @Override public void connectionLost(Throwable cause) { Log.d(TAG, "connectionLost: 连接断开"); } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { Log.d(TAG, "收到消息:"+message.toString()); } @Override public void deliveryComplete(IMqttDeliveryToken token) { } }); ===== 3. 更多信息 ===== * 完整demo示例,请参见[[https://github.com/wangxinjeff/mqttdemo-android|demo下载]]。 * 目前MQTT客户端支持多种语言,请参见 [[http://docs-im.easemob.com/playground/message/sdkdownload|SDK下载]]。 * 如果您在使用MQTT服务中,有任何疑问和建议,欢迎您[[http://docs-im.easemob.com/playground/message/msgcontact|联系我们]]。