Get context in an okhttp3 WebSocketListener class in Kotlin

63 views Asked by At

I am currently working on a project that aims to communicate with android devices inside a car. I chose okhttp3 websockets to achieve this goal. My issue is that I can't get the context to display an alertdialog to the user. Here is an overview of my implementation.

MainActivity.kt

import LocationClient
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val loc = LocationClient(context = this) //TODO create a work manager for this
        loc.getLocation()
    }

}

The main activity calls the getLocation method that sends GPS location to the websocket

LocationClient.kt

class LocationClient(private val context: Context) : LocationListener {
    private val websocketObject: WebsocketObject = WebsocketObject
...
    override fun onLocationChanged(location: Location) {
        websocketObject.sendLocation(location)
    }
...

I have included the main parts of the LocationClient above. Basically it just creates the WebsocketObject and calls the appropriate method

WebsocketObject.kt

object WebsocketObject {
    init {
        Log.d("WebsocketObject", "Object created")
    }

    private val request = Request.Builder().url("myWebsocketURL").build()
    private val listener = WebsocketListener()
    private val client = OkHttpClient()
    private val ws = client.newWebSocket(request, listener)

    fun sendLocation(location: Location) {
        ws.send("MyJsonpayload")
    }

    fun sendPickupRequestResponse() {
        //TODO create an alertdialog and send the user response to the websocket

        ws.send("MyJsonpayload")

    }
}

Just to be torough, here is where sendPickupRequestResponse() is called

WebsocketListener.kt

class WebsocketListener(): WebSocketListener() {
    private val websocketObject: WebsocketObject = WebsocketObject


    override fun onMessage(webSocket: WebSocket, text: String) {
        // Handle incoming WebSocket messages.
        Log.d("websocketconn", "Websocket message received: ${text}")

        //pickup_request event
        if ("myPickupRequestEvent") {
            
            websocketObject.sendPickupRequestResponse()
        }
    }

I have put the request.builder in a singleton object because I think it is best to reuse the same connection every time, however due to this I can't send the context to this method and thus cannot create the alertdialog.

I would greatly appreciate if you could let me know if my implementation is correct and how I can solve my context problem.

Thanks a bunch !

I have tried to create and call a function from MainActivity to create the alertdialog but I got this error Can't create handler inside thread Thread[OkHttp ...] that has not called Looper.prepare()

I have tried to pass context to the object but learned that it creates mem leaks

I have tried using companion objects in my activity but I can't get context in there either

What I want to achieve is to create an alert dialog in order to get confirmation from the user and then sends the response to my websocket object

0

There are 0 answers