socket-io android 无法在启用 pro-guard 的情况下工作

问题描述 投票:0回答:1

我正在尝试启动 android 前台服务,以便使用 Socket-IO android 本机客户端与我的服务器进行实时连接,并且 当我使用调试模式运行应用程序时它可以工作但是当我使用 释放模式运行它时仅连接事件执行,其他事件不起作用

服务.kt

class MyService() : Service() {


    private val notifBuilder = NotificationCompat.Builder(this, ongoingChannelId)
        .setSmallIcon(R.drawable.ic_notification_offline)
        .setPriority(NotificationCompat.PRIORITY_MIN)
        .setOngoing(true)


    override fun onCreate() {
        Log.e(TAG, "onCreate: Service ONCREATE")
        notificationIntent = Intent(this, MainActivity::class.java)
        pendingIntent = PendingIntent.getActivity(
            applicationContext,
            0, notificationIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT),
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
        )
        notifBuilder.setContentIntent(pendingIntent)
            .setOnlyAlertOnce(true)
            .setContentTitle(getString(R.string.app_name))

        super.onCreate()
    }


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.e(TAG, "onStartCommand: ")
        createNotificationChannel()
        startForeground(onGoingNotificationId, notifBuilder.build())
        startSocket()
        return START_STICKY
    }


    private fun startSocket() {
        if (!socketStarted) {
            socketStarted = true
            socket.on(Socket.EVENT_CONNECT) {
                Log.e(TAG, "onStartCommand: ${Socket.EVENT_CONNECT}")
                notifBuilder.setContentText("Connected to Server")
                NotificationManagerCompat.from(this)
                    .notify(onGoingNotificationId, notifBuilder.build())
                socket.emit(
                    SOCKET_EVENT_LOGIN,
                    "my token"
                )
                if (this::pingTimerTask.isInitialized)
                    pingTimerTask.cancel()
                pingTimerTask = object : TimerTask() {
                    override fun run() {
                        Log.e(TAG, "run: Pinging ".plus(socket.connected()))
                        if (socket.connected())
                            socket.emit(
                                SOCKET_EVENT_PING,
                                "my token"
                            )
                    }
                }

                pingTimer = if (!this::pingTimer.isInitialized)
                    Timer(true)
                else {
                    pingTimer.cancel()
                    pingTimer.purge()
                    Timer(true)
                }
                pingTimer.schedule(pingTimerTask, 2000, 10000)

            }
            socket.on(Socket.EVENT_CONNECT_ERROR) {
                Log.e(TAG, "onStartCommand: ${Socket.EVENT_CONNECT_ERROR}")
                notifBuilder.setContentText("Connection error to Server")
                    .setSmallIcon(R.drawable.ic_notification_offline)
                NotificationManagerCompat.from(this)
                    .notify(onGoingNotificationId, notifBuilder.build())
                pingTimer.cancel()
            }
            socket.on(Socket.EVENT_DISCONNECT) {
                Log.e(TAG, "onStartCommand: ${Socket.EVENT_DISCONNECT}")
                notifBuilder.setContentText("Disconnected from Server")
                notifBuilder.setOngoing(false)
                    .setSmallIcon(R.drawable.ic_notification_offline)
                NotificationManagerCompat.from(this)
                    .notify(onGoingNotificationId, notifBuilder.build())
                pingTimer.cancel()
            }
            socket.on(SOCKET_EVENT_ONLINE, loginListener)
            socket.connect()
        }
    }

    @SuppressLint("MissingPermission")
    private val loginListener = Emitter.Listener { res ->
        Log.e(TAG, "loginListener: Pinged")
        val date = System.currentTimeMillis()
        val dateFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
        val dateStr: String = dateFormat.format(date)
        notifBuilder.setContentText("Last Ping was $dateStr")
            .setSmallIcon(R.drawable.ic_notification_online)
        NotificationManagerCompat.from(this).notify(onGoingNotificationId, notifBuilder.build())

    }

}

所以我希望每次 ping 服务器时都能得到一个登录侦听器事件

我像这样启动服务

serviceIntent = Intent(requireContext(), MyService::class.java)
ContextCompat.startForegroundService(requireContext(),serviceIntent)

更新

因此在发布版本中禁用 proguard 后,它开始工作!

android kotlin socket.io foreground-service
1个回答
0
投票

我在 proguard 文件中定义了我的模型类。

-keep class com.example.model.** { *; }

如果您使用 SSL,这可能就是原因。 这样就可以正常工作了:

val socket = IO.socket(socketUrl, SocketOptionsSSL.getOptions())
socketConnect()

private fun socketConnect() {
val obj = JSONObject()
obj.put("type", "client")
obj.put("userId", "XXXX")
socket.emit("roomConnect", obj)
socket.on("tableupdate", onSocketTableStateChange())
socket.connect()
}
private fun onSocketTableStateChange(): Emitter.Listener {
return object : Emitter.Listener {
override fun call(vararg args: Any?) {
try {
val socketData = Gson().fromJson(args[0].toString(), SocketDataClass::class.java)
} catch (e: Exception) {
}
}
}
}

SocketOptionsSSL

public class SocketOptionsSSL {

public static IO.Options getOptions() {


    HostnameVerifier hostnameVerifier = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
    TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
        @Override
        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {

        }

        @Override
        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {

        }

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[0];
        }
    }};

    X509TrustManager trustManager = (X509TrustManager) trustAllCerts[0];

    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .hostnameVerifier(hostnameVerifier)
            .build();
    try {
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, null);
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        okHttpClient = null;
        okHttpClient = new OkHttpClient.Builder()
                .hostnameVerifier(hostnameVerifier)
                .sslSocketFactory(sslSocketFactory, trustManager)
                .build();
    } catch (Exception e) {
        Logger.INSTANCE.d("SocketSSL", "Options çekilirken hata oluştu.");

    }

    IO.Options opts = new IO.Options();
    opts.callFactory = okHttpClient;
    opts.webSocketFactory = okHttpClient;

    return opts;
}
}
© www.soinside.com 2019 - 2024. All rights reserved.