0

I'm trying to connect a client Android app written in Kotlin to a localhost Python server on my PC so I can click a button, open a socket, send a message to the server, have the server send a message back and then close that connection.

I've been able to find some code with similar functionality, but it's all in Java and I'm really new to this, so I haven't been able to properly tweak it.

I believe this is the closest to what I'm looking for, it's another person's code from one of the questions on this site, but they couldn't get it to work and nobody responded:

class MainActivity : AppCompatActivity() {
    var button: Button? = null
    var editText: EditText? = null
    var textView: TextView? = null
    private var clientSocket: Socket? = null
    private var socketIn: BufferedReader? = null
    private var socketOut: PrintWriter? = null
    private val port = 10000
    private val ip = "192.168.*.***"
    private var myHandler: MyHandler? = null
    private var myThread: MyThread? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val policy =
            StrictMode.ThreadPolicy.Builder().permitAll().build()
        StrictMode.setThreadPolicy(policy)
        try {
            clientSocket = Socket(ip, port)
            socketIn =
                BufferedReader(InputStreamReader(clientSocket!!.getInputStream()))
            socketOut = PrintWriter(clientSocket!!.getOutputStream(), true)
        } catch (e: Exception) {
            e.printStackTrace()
        }

        myHandler = MyHandler()
        myThread = MyThread()
        myThread!!.start()
        button = findViewById<View>(R.id.sendMessage_button) as Button
        textView = findViewById<View>(R.id.serverResponse_textView) as TextView

        button!!.setOnClickListener {
            editText = findViewById<View>(R.id.typeMessage_editText) as EditText
            val toSend = editText!!.text.toString()
            /*socketPython.Datastack.printStack();
            textView.setText((String)SocketwithPython.Datastack.Peek(0));
            */
            socketOut!!.write(toSend)
        }
    }

    internal inner class MyThread : Thread() {
        override fun run() {
            while (true) {
                try {
                    println("Trying to read...")
                    val data = socketIn!!.readLine()
                    val msg = myHandler!!.obtainMessage()
                    msg.obj = data
                    myHandler!!.sendMessage(msg)
                    println(data)
                    socketOut!!.print(
                        """
                            Try
                            
                            """.trimIndent()
                    )
                    socketOut!!.flush()
                    println("Message sent")
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }

    internal inner class MyHandler : Handler() {
        override fun handleMessage(msg: Message) {
            textView!!.text = msg.obj.toString()
        }
    }
} 

I converted it to Kotlin and I've tried to work through it a bit, but I'm lost and I'm limited on resources. The original code is here: Python(Server) Android(Client) Socket Programming. It also may just be worthwhile to scrap that idea and do it from scratch, I really have no idea.

I've also tried adapting this one from this post: Socket Programming with Python server and Android client:

class MainActivity : AppCompatActivity() {

    private var socket: Socket? = null

    companion object {
        private const val SERVERPORT = 10000
        private const val SERVER_IP = "192.168.1.204"
    }

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

        Thread(ClientThread()).start()
    }


    fun onClick(view: View?) {
        try {
            socket = Socket(SERVER_IP, SERVERPORT)
            val fromClient = findViewById<View>(R.id.typeMessage_editText) as EditText
            val clientMessage = fromClient.text.toString()
            val toServer = PrintWriter(socket!!.getOutputStream(), true)

            toServer.write(clientMessage)
            toServer.close()

        } catch (e: UnknownHostException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    internal inner class ClientThread : Runnable {
        override fun run() {
            try {
                val serverAddr: InetAddress =
                    InetAddress.getByName(SERVER_IP)
                socket = Socket(serverAddr, SERVERPORT)
            } catch (e1: UnknownHostException) {
                e1.printStackTrace()
            } catch (e1: IOException) {
                e1.printStackTrace()
            }
        }
    }

}

Thanks.

I've added a screenshot of what the view looks like in case that helps:

enter image description here

ocrdu
  • 2,172
  • 6
  • 15
  • 22
  • `Thread(ClientThread()).start()` Yes you should use a Thread. But you cannot use the code in the following onClick to start another client (why another) without using a thread. – blackapps Jan 04 '21 at 19:39

0 Answers0