HDLSDK/app/src/main/AndroidManifest.xml
@@ -12,13 +12,14 @@ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:name=".App" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.HDLSDK"> <activity android:name=".device.DevicesListActivity"></activity> <activity android:name=".MainActivity" android:exported="true"> HDLSDK/app/src/main/java/com/hdl/hdlsdk/MainActivity.java
@@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView; import android.Manifest; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; @@ -19,6 +20,7 @@ import com.chad.library.adapter.base.BaseQuickAdapter; import com.chad.library.adapter.base.listener.OnItemClickListener; import com.google.gson.reflect.TypeToken; import com.hdl.hdlsdk.device.DevicesListActivity; import com.hdl.sdk.common.event.EventListener; import com.hdl.sdk.common.exception.HDLLinkException; import com.hdl.sdk.common.utils.IdUtils; @@ -97,6 +99,7 @@ beans.add(new DemoBean("读取状态")); beans.add(new DemoBean("获取场景列表")); beans.add(new DemoBean("场景控制")); beans.add(new DemoBean("设备功能列表")); demoAdapter = new DemoAdapter(beans); rv.setAdapter(demoAdapter); @@ -142,6 +145,10 @@ case 7: //获取场景列表 controlScene(); break; case 8: //功能列表 startDevicesListActivity(); break; } } @@ -313,6 +320,7 @@ @Override public void onError(HDLLinkException e) { tv.setText("网关不在线"); responseTv.setText(e.getMsg()); } @Override public void onSuccess(GatewaySearchBean gatewaySearchBean) { @@ -464,4 +472,8 @@ } void startDevicesListActivity(){ Intent intent = new Intent(this, DevicesListActivity.class); startActivity(intent); } } HDLSDK/app/src/main/java/com/hdl/hdlsdk/device/DevicesListActivity.java
New file @@ -0,0 +1,89 @@ package com.hdl.hdlsdk.device; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.OrientationHelper; import androidx.recyclerview.widget.RecyclerView; import android.annotation.SuppressLint; import android.os.Bundle; import android.util.Log; import com.google.gson.reflect.TypeToken; import com.hdl.hdlsdk.DemoAdapter; import com.hdl.hdlsdk.R; import com.hdl.sdk.common.exception.HDLLinkException; import com.hdl.sdk.common.utils.LogUtils; import com.hdl.sdk.common.utils.gson.GsonConvert; import com.hdl.sdk.connect.HDLLink; import com.hdl.sdk.connect.bean.LinkResponse; import com.hdl.sdk.connect.bean.response.BaseLocalResponse; import com.hdl.sdk.connect.bean.response.GatewaySearchBean; import com.hdl.sdk.connect.callback.HDLLinkCallBack; import java.util.ArrayList; import java.util.List; public class DevicesListActivity extends AppCompatActivity { private static final String TAG = "DevicesListActivity"; private List<FunctionBean> devicesList = new ArrayList<>(); private DevicesListAdapter mDevicesListAdapter; private RecyclerView mRecyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_devices_list); initView(); initData(); } @SuppressLint("WrongConstant") private void initView() { mRecyclerView = findViewById(R.id.device_list_rv); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); mDevicesListAdapter = new DevicesListAdapter(this, devicesList); mRecyclerView.setAdapter(mDevicesListAdapter); } private void initData() { getFunctionList(); } /** * 获取功能列表 */ void getFunctionList(){ HDLLink.getInstance().getFunctionList(new HDLLinkCallBack() { @Override public void onError(HDLLinkException error) { Log.e(TAG,error.getMsg()); } @Override public void onSuccess(String data) { Log.i(TAG, "获取设备列表成功"); handelFunList(data); } }); } void handelFunList(String data){ try { final LinkResponse linkResponse = GsonConvert.getGson().fromJson(data, new TypeToken<LinkResponse>() { }.getType()); final BaseLocalResponse<List<FunctionBean>> bean = GsonConvert.getGson().fromJson(linkResponse.getData(), new TypeToken<BaseLocalResponse<List<FunctionBean>>>() { }.getType()); devicesList.clear(); devicesList.addAll(bean.getObjects()); mDevicesListAdapter.notifyDataSetChanged(); }catch (Exception e){ Log.e(TAG, "handelFunList: " + e.getMessage()); } } } HDLSDK/app/src/main/java/com/hdl/hdlsdk/device/DevicesListAdapter.java
New file @@ -0,0 +1,69 @@ package com.hdl.hdlsdk.device; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; import com.chad.library.adapter.base.BaseMultiItemQuickAdapter; import com.chad.library.adapter.base.viewholder.BaseViewHolder; import com.hdl.hdlsdk.DemoBean; import com.hdl.hdlsdk.R; import java.util.List; public class DevicesListAdapter extends RecyclerView.Adapter<DevicesListAdapter.ViewHolder> { private LayoutInflater mInflater; private List<FunctionBean> mList = null; public DevicesListAdapter(Context context, List<FunctionBean> devicesList) { this.mInflater = LayoutInflater.from(context); this.mList = devicesList; } /** * item显示类型 * * @param parent * @param viewType * @return */ @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = mInflater.inflate(R.layout.item_devices_list, parent, false); ViewHolder viewHolder = new ViewHolder(view); return viewHolder; } /** * 数据的绑定显示 * * @param holder * @param position */ @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.item_tv.setText(mList.get(position).getName()); } @Override public int getItemCount() { return mList.size(); } //自定义的ViewHolder,持有每个Item的的所有界面元素 public static class ViewHolder extends RecyclerView.ViewHolder { public TextView item_tv; public ViewHolder(View view) { super(view); item_tv = (TextView) view.findViewById(R.id.device_title_tv); } } } HDLSDK/app/src/main/java/com/hdl/hdlsdk/device/FunctionBean.java
New file @@ -0,0 +1,106 @@ package com.hdl.hdlsdk.device; import com.chad.library.adapter.base.entity.MultiItemEntity; import java.io.Serializable; import java.util.List; /** * Created by jlchen on 12/7/21. */ public class FunctionBean implements Serializable { private String sid; private String oid; private String name; private String spk; private String omodel; private String src; private String online; private List<FunctionStatus> status; public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } public String getOid() { return oid; } public void setOid(String oid) { this.oid = oid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSpk() { return spk; } public void setSpk(String spk) { this.spk = spk; } public String getOmodel() { return omodel; } public void setOmodel(String omodel) { this.omodel = omodel; } public String getSrc() { return src; } public void setSrc(String src) { this.src = src; } public String getOnline() { return online; } public void setOnline(String online) { this.online = online; } public List<FunctionStatus> getStatus() { return status; } public void setStatus(List<FunctionStatus> status) { this.status = status; } public class FunctionStatus implements Serializable { private String key; private String value; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } } HDLSDK/app/src/main/res/layout/activity_devices_list.xml
New file @@ -0,0 +1,14 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".device.DevicesListActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/device_list_rv" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> HDLSDK/app/src/main/res/layout/item_devices_list.xml
New file @@ -0,0 +1,44 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="50dp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal"> <TextView android:id="@+id/device_title_tv" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="@dimen/dp_10" android:gravity="center|left" android:text="设备" android:textColor="@color/black" android:layout_weight="1"/> <Switch android:id="@+id/device_on_off_switch" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="@dimen/dp_10" /> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:layout_marginStart="10dp" android:layout_marginEnd="10dp" android:background="#f5f5f5" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> </LinearLayout> HDLSDK/hdl-common/src/main/java/com/hdl/sdk/common/exception/HDLLinkCode.java
@@ -14,6 +14,7 @@ HDL_TIMEOUT_ERROR(-2004,"超时"), HDL_UNAUTHORIZED_ERROR(-2005,"未认证,请先认证"), HDL_AUTH_ERROR_GATEWAY_NOT_REGISTERED(-2006,"认证失败,网关未注册到云端"), HDL_SEARCH_GATEWAY_TIMEOUT_ERROR(-2007,"搜索网关失败,超时"), HDL_GET_DEVICE_LIST_ERROR(-2100,"获取设备列表失败"), HDL_GET_FUNCTION_LIST_ERROR(-2101,"获取功能列表失败"), HDL_GET_FUNCTION_PROPERTIES_ERROR(-2102,"获取功能属性失败"), HDLSDK/hdl-connect/build.gradle
@@ -9,7 +9,7 @@ minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion versionCode 1 versionName "1.0" versionName "1.0.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLAuthSocket.java
@@ -1,5 +1,6 @@ package com.hdl.sdk.connect.socket; import android.net.ipsec.ike.TunnelModeChildSessionParams; import android.text.TextUtils; import com.google.gson.Gson; @@ -10,6 +11,7 @@ import com.hdl.sdk.common.exception.HDLLinkCode; import com.hdl.sdk.common.exception.HDLLinkException; import com.hdl.sdk.common.utils.LogUtils; import com.hdl.sdk.common.utils.ThreadToolUtils; import com.hdl.sdk.connect.bean.response.AuthenticateResponse; import com.hdl.sdk.connect.bean.response.NetworkAccessBroadcastResponse; import com.hdl.sdk.connect.callback.BaseCallBack; @@ -36,6 +38,9 @@ import java.io.UnsupportedEncodingException; import java.util.List; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import static com.hdl.sdk.common.config.TopicConstant.DEIVCE_AUTH_REQUEST; @@ -51,7 +56,9 @@ */ private static final int UDP_PORT = 8585; private static SocketBoot updBoot; // private EventListener authEvent; // private EventListener authEvent; //搜索网关 private EventListener searchGatewayEvent; /** * udp默认组播ip */ @@ -61,6 +68,10 @@ * instance */ private volatile static HDLAuthSocket instance; private HDLAuthSocket() { initSearchGatewayEvent(); } // public interface CallBack extends BaseCallBack { // void onSuccess(String msg); @@ -117,10 +128,10 @@ @Override public void onMessage(Object msg) { NetworkAccessBroadcastResponse bean = getNetworkAccessBroadcastResponse(msg); if(bean != null){ if (bean != null) { LogUtils.i(TAG, "网关入网广播IP: " + bean.getIPAddress()); String ipStr = bean.getIPAddress(); if(!TextUtils.isEmpty(ipStr)){ if (!TextUtils.isEmpty(ipStr)) { sendAuthenticateRequest(ipStr, request, callBack); } } @@ -134,7 +145,7 @@ /** * 结束监听入网及认证广播 */ public void endAuthenticateRequest(){ public void endAuthenticateRequest() { //移除监听 EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_AUTH_BROADCAST); } @@ -158,21 +169,21 @@ HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() { @Override public void onSucceed(Object msg) { if(callBack == null) return; if (callBack == null) return; AuthenticateResponse bean = getAuthenticateResponseBean(msg); if(bean != null){ if (bean != null) { String localSecret = bean.getAuth().getLocalSecret(); String gatewayId = bean.getObjects().getGatewayID(); String ipAddress = bean.getObjects().getIPAddress(); //判断网关是否已经注册到云端 if(TextUtils.isEmpty(localSecret) ||TextUtils.isEmpty(gatewayId)){ if (TextUtils.isEmpty(localSecret) || TextUtils.isEmpty(gatewayId)) { //认证失败,网关未注册到云端 callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_AUTH_ERROR_GATEWAY_NOT_REGISTERED)); }else{ HDLLinkConfig.getInstance().saveConfig(localSecret,gatewayId,ipAddress); } else { HDLLinkConfig.getInstance().saveConfig(localSecret, gatewayId, ipAddress); callBack.onSuccess("认证成功"); } }else{ } else { callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_ERROR)); } } @@ -180,7 +191,7 @@ @Override public void onFailure() { LogUtils.i(TAG, "onFailure: "); if(callBack == null) return; if (callBack == null) return; callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR)); } }); @@ -229,7 +240,7 @@ // sendAuthenticateRequest(ip, request, callBack); // } public interface SearchGatewayCallBack extends BaseCallBack{ public interface SearchGatewayCallBack extends BaseCallBack { /** * 搜索网关成功 * @@ -256,7 +267,8 @@ /** * 组播搜索指定网关是否在线,搜索到则返回指定的网关对象 * @param callBack 回调 * * @param callBack 回调 */ public void searchGatewayMulticast(SearchGatewayCallBack callBack) { searchGateway(HDLLinkConfig.getInstance().getGatewayId(), UDP_GROUP_IP, callBack); @@ -264,49 +276,14 @@ /** * 组播搜索指定网关是否在线,搜索到则返回指定的网关对象 * @param callBack 回调 * * @param callBack 回调 */ public void searchGatewayBroadcast(SearchGatewayCallBack callBack) { String ip = IpUtils.getBroadcastAddress(); searchGateway(HDLLinkConfig.getInstance().getGatewayId(), ip, callBack); } /** * 搜索指定网关是否在线,搜索到则返回指定的网关对象 * * @param gatewayId 网关id * @param ip 接收目标的ip地址 * @param callBack 回调 */ public void searchGateway(String gatewayId, String ip, SearchGatewayCallBack callBack) { String time = String.valueOf(System.currentTimeMillis()); JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("id", IdUtils.getUUId()); jsonObject.addProperty("time_stamp", time); LinkRequest message = new LinkRequest(TopicConstant.GATEWAY_SEARCH, jsonObject.toString()); HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() { @Override public void onSucceed(Object msg) { GatewaySearchBean searchBean = getGatewaySearchBean(msg); if (searchBean != null && searchBean.getGatewayId().contains(gatewayId)) { LogUtils.i(TAG, "onSuccess: "); HDLLinkConfig.getInstance().setCurrentGateway(searchBean); HDLLinkConfig.getInstance().setLocalEncrypt(searchBean.isLocalEncrypt()); callBack.onSuccess(searchBean); }else { } } @Override public void onFailure() { LogUtils.i(TAG, "onFailure: "); callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR)); } }); } @@ -327,13 +304,13 @@ HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() { @Override public void onSucceed(Object msg) { if(callBack == null) return; if (callBack == null) return; callBack.onSuccess("控制成功"); } @Override public void onFailure() { if(callBack == null) return; if (callBack == null) return; callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_CONTROL_FAILURE_ERROR)); } }); @@ -343,13 +320,14 @@ /** * 通用发送指令 * 1秒没响应就让他重新发送,重试3次 * @param topic 发送数据 * @param bodyStr 回复的主题 * * @param topic 发送数据 * @param bodyStr 回复的主题 * @param callBack 回调 */ public void udpSendMsg(String topic, String bodyStr, HDLLinkResponseCallBack callBack) { if(TextUtils.isEmpty(topic) || TextUtils.isEmpty(bodyStr)) { if(callBack != null){ if (TextUtils.isEmpty(topic) || TextUtils.isEmpty(bodyStr)) { if (callBack != null) { callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_DATA_NULL_ERROR)); } return; @@ -359,13 +337,13 @@ HdlSocketHelper.send(getUdpBoot(ip), message, new HdlSocketHelper.HdlSocketListener() { @Override public void onSucceed(Object msg) { if(callBack == null) return; if (callBack == null) return; callBack.onSuccess((LinkResponse) msg); } @Override public void onFailure() { if(callBack == null) return; if (callBack == null) return; callBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_TIMEOUT_ERROR)); } } @@ -403,7 +381,7 @@ return mBean; } private NetworkAccessBroadcastResponse getNetworkAccessBroadcastResponse(Object msg){ private NetworkAccessBroadcastResponse getNetworkAccessBroadcastResponse(Object msg) { NetworkAccessBroadcastResponse mBean = null; if (msg instanceof LinkResponse) { LinkResponse linkResponse = (LinkResponse) msg; @@ -418,4 +396,121 @@ return mBean; } /** * 网关搜索相关 */ private static final int MAX_SEARCH_COUNT = 10;//总共搜索测试 private final AtomicInteger searchGatewayCount = new AtomicInteger(0);; private final AtomicBoolean isSearchGatewaySuccess = new AtomicBoolean(true); private String searchGatewayId = ""; private SearchGatewayCallBack mSearchGatewayCallBack; private void initSearchGatewayEvent(){ LogUtils.i("搜索网关--","initSearchGatewayEvent"); searchGatewayEvent = new EventListener() { @Override public void onMessage(Object msg) { try { if (msg instanceof LinkResponse) { LinkResponse linkResponse = (LinkResponse) msg; String data = linkResponse.getData(); if (!TextUtils.isEmpty(data)) { final BaseLocalResponse<GatewaySearchBean> response = GsonConvert.getGson().fromJson(data, new TypeToken<BaseLocalResponse<GatewaySearchBean>>() { }.getType()); GatewaySearchBean searchBean = response.getObjects(); if (searchBean != null && !TextUtils.isEmpty(searchBean.getGatewayId())) { if (searchBean.getGatewayId().contains(searchGatewayId)) { removeSearchGatewayEvent();//移除搜索网关监听 isSearchGatewaySuccess.set(true);//搜索成功标记 searchGatewayCount.set(11);//次数标记 if(mSearchGatewayCallBack != null){ mSearchGatewayCallBack.onSuccess(searchBean); } } } } } } catch (Exception e) { } } }; } /** * 搜索指定网关是否在线,搜索到则返回指定的网关对象 * * @param gatewayId 网关id * @param ip 接收目标的ip地址 * @param callBack 回调 */ public void searchGateway(String gatewayId, String ip, SearchGatewayCallBack callBack) { this.searchGatewayId = gatewayId; this.mSearchGatewayCallBack = callBack; //重置参数 searchGatewayCount.set(0); isSearchGatewaySuccess.set(false); String time = String.valueOf(System.currentTimeMillis()); JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("id", IdUtils.getUUId()); jsonObject.addProperty("time_stamp", time); LinkRequest message = new LinkRequest(TopicConstant.GATEWAY_SEARCH, jsonObject.toString()); //注册搜索网关监听 registerSearchGatewayEvent(); new Thread(new Runnable() { @Override public void run() { while (searchGatewayCount.get() < 10 && (!isSearchGatewaySuccess.get()) ) { try { //搜索网关 searchGatewayCount.set(searchGatewayCount.get() + 1); LogUtils.i("搜索网关--","搜索网关第"+searchGatewayCount.get()+"次"); getUdpBoot(ip).sendMsg(message.getSendBytes()); Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } } if(!isSearchGatewaySuccess.get()){ //搜索10次,指定网关都没回复,回调超时 callBackSearchGatewayTimeout(); LogUtils.e("搜索网关--","搜索10次,指定网关都没回复,回调超时"); } } }).start(); } /** * 注册搜索网关监听 */ private void registerSearchGatewayEvent(){ LogUtils.i("搜索网关--","注册搜索网关监听"); EventDispatcher.getInstance().registerIo(TopicConstant.GATEWAY_SEARCH_REPLY, searchGatewayEvent); } /** * 移除搜索网关监听 */ private void removeSearchGatewayEvent(){ LogUtils.i("搜索网关--","移除搜索网关监听"); EventDispatcher.getInstance().remove(TopicConstant.GATEWAY_SEARCH_REPLY, searchGatewayEvent); } /** * 回调搜索网关超时 */ private void callBackSearchGatewayTimeout(){ removeSearchGatewayEvent(); ThreadToolUtils.getInstance().runOnUiThread(new Runnable() { @Override public void run() { if(mSearchGatewayCallBack != null){ mSearchGatewayCallBack.onError(HDLLinkException.getErrorWithCode(HDLLinkCode.HDL_SEARCH_GATEWAY_TIMEOUT_ERROR)); } } }); } } HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HDLSocket.java
@@ -11,6 +11,7 @@ import com.hdl.sdk.common.exception.HDLLinkException; import com.hdl.sdk.common.utils.IdUtils; import com.hdl.sdk.common.utils.IpUtils; import com.hdl.sdk.common.utils.LogUtils; import com.hdl.sdk.common.utils.SPUtils; import com.hdl.sdk.common.utils.ThreadToolUtils; import com.hdl.sdk.common.utils.gson.GsonConvert; @@ -696,12 +697,14 @@ @Override public void onMessage(Object msg) { if (msg instanceof LinkResponse) { LogUtils.e("sendMsg onSuccess"); if (callBack != null) { callBack.onSuccess(msg.toString()); } threadPool.shutdownNow(); } LogUtils.e("sendMsg eventListener remove"); EventDispatcher.getInstance().remove(eventTag, this); } }; @@ -713,6 +716,7 @@ getTcp().sendMsg(data); } else { threadPool.shutdownNow(); LogUtils.e("sendMsg eventListener remove"); EventDispatcher.getInstance().remove(eventTag, eventListener); ThreadToolUtils.getInstance().runOnUiThread(new Runnable() { @Override HDLSDK/hdl-connect/src/main/java/com/hdl/sdk/connect/socket/HdlSocketHelper.java
@@ -129,5 +129,7 @@ if (listener != null) { listener.onFailure(); } EventDispatcher.getInstance().remove(eventListener); } }