• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps Android Socket Client

Hi,

I'm doing a desktop server application in java with android clients. I'm using sockets to provide the communication.

I have create an instance of tcpClient on MainActivity and I would like to know how could I call the method 'sendMessage' on other activities.

Should I create an instance of tcpClient on all activities?

Thanks

Server class
Code:
import java.net.*;
import java.io.*;

public class Server {

    public static void main(String[] args) throws IOException{

        boolean listening = true;

        try (ServerSocket serverSocket = new ServerSocket(4444)){

            while(listening){
                new ServerThread(serverSocket.accept()).start();
            }
        } catch (IOException e) {
            System.out.println("Could not listen on port: 4444");
            System.exit(-1);
        }

    }
}


ServerThread
Code:
import java.net.*;
import java.io.*;

public class ServerThread extends Thread {
   
    private Socket socket = null;

    public ServerThread(Socket socket) {
        super("ServerThread");
        this.socket = socket;
    }
   
    public void run() {

        try (
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(
                new InputStreamReader(
                    socket.getInputStream()));
        ) {
            String inputLine, outputLine;
            GameProtocol gp = new GameProtocol();
            outputLine = gp.processInput(null);
            //System.out.println(outputLine);
            //out.println(outputLine);

            while ((inputLine = in.readLine()) != null) {
                //System.out.println(outputLine);
                outputLine = gp.processInput(inputLine);
                System.out.println(outputLine);
                out.println(outputLine);
                if (outputLine.equals("Bye"))
                    break;
            }
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
]

TcpClient class
Code:
import android.util.Log;

import java.io.*;
import java.net.*;

/**
 * Created by andrecorreia on 03/06/16.
 */
public class TcpClient {

    public static final String SERVER_IP = "10.0.2.2"; // computer IP address
    public static final int SERVER_PORT = 4444;

    // message to send to the server
    private String mServerMessage;
    // sends message received notifications
    private OnMessageReceived mMessageListener = null;
    // while this is true, the server will continue running
    private boolean mRun = false;
    // used to send messages
    private PrintWriter mBufferOut;
    // used to read messages from the server
    private BufferedReader mBufferIn;

    /**
     * Constructor of the class. OnMessagedReceived listens for the messages received from server
     */
    public TcpClient(OnMessageReceived listener) {
        mMessageListener = listener;
    }

    /**
     * Sends the message entered by client to the server
     *
     * @param message text entered by client
     */
    public void sendMessage(String message) {
        if (mBufferOut != null && !mBufferOut.checkError()) {
            mBufferOut.println(message);
            mBufferOut.flush();
        }
    }

    /**
     * Close the connection and release the members
     */
    public void stopClient() {
        Log.i("Debug", "stopClient");

        // send mesage that we are closing the connection
        //sendMessage(Constants.CLOSED_CONNECTION + "Kazy");

        mRun = false;

        if (mBufferOut != null) {
            mBufferOut.flush();
            mBufferOut.close();
        }

        mMessageListener = null;
        mBufferIn = null;
        mBufferOut = null;
        mServerMessage = null;
    }

    public void run() {

        mRun = true;

        try {
            //here you must put your computer's IP address.
            InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

            //InetAddress serverAddr = InetAddress.getLocalHost();
            Log.e("TCP Client", "C: Connecting...");

            //create a socket to make the connection with the server
            Socket socket = new Socket("192.168.1.92", SERVER_PORT);

            try {
                Log.i("Debug", "inside try catch");
                //sends the message to the server
                mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

                //receives the message which the server sends back
                mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // send login name
                //sendMessage(Constants.LOGIN_NAME + PreferencesManager.getInstance().getUserName());
                //sendMessage("Hi");
                //in this while the client listens for the messages sent by the server
                while (mRun) {
                    mServerMessage = mBufferIn.readLine();
                    if (mServerMessage != null && mMessageListener != null) {
                        //call the method messageReceived from MyActivity class
                        mMessageListener.messageReceived(mServerMessage);
                    }

                }
                Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");

            } catch (Exception e) {

                Log.e("TCP", "S: Error", e);

            } finally {
                //the socket must be closed. It is not possible to reconnect to this socket
                // after it is closed, which means a new socket instance has to be created.
                socket.close();
            }

        } catch (Exception e) {

            Log.e("TCP", "C: Error", e);

        }

    }

    //Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
    //class at on asynckTask doInBackground
    public interface OnMessageReceived {
        public void messageReceived(String message);
    }
}

Main Activity
Code:
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;


public class MainActivity extends Activity implements OnClickListener {

    public static TcpClient tcpClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new ConnectTask().execute("");

        // Set up click listeners for all the buttons
        View playNowButton = findViewById(R.id.playNow_button);
        playNowButton.setOnClickListener(this);

        View optionsButton = findViewById(R.id.options_button);
        optionsButton.setOnClickListener(this);

        View helpButton = findViewById(R.id.help_button);
        helpButton.setOnClickListener(this);

        View exitButton = findViewById(R.id.exit_button);
        exitButton.setOnClickListener(this);
        //---------------------------------------------
    }


    @Override
    public void onClick(View v) {
        Intent i;
        switch (v.getId()){
            case R.id.playNow_button:
                i = new Intent(this, PlayNowActivity.class);
                startActivity(i);
                break;
            case R.id.options_button:
                i = new Intent(this, OptionsActivity.class);
                tcpClient.sendMessage("options");
                startActivity(i);
                break;
            case R.id.help_button:
                i = new Intent(this, HelpActivity.class);
                tcpClient.sendMessage("help");
                startActivity(i);
                break;
            case R.id.exit_button:
                finish();
                break;
        }
    }

    public class ConnectTask extends AsyncTask<String,String,TcpClient> {

        @Override
        protected TcpClient doInBackground(String... message) {

            //we create a TCPClient object and
            tcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
                @Override
                //here the messageReceived method is implemented
                public void messageReceived(String message) {

                    //this method calls the onProgressUpdate
                    publishProgress(message);

                }
            });
            tcpClient.run();

            return null;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
        /*View view = adapter.getChildView(0, 0, false, null, null);
        TextView text = (TextView) view.findViewById(R.id.betChildOdd);
        child2.get(0).get(0).put("OLD", text.getText().toString());
        child2.get(0).get(0).put(CONVERTED_ODDS, values[0].toString());
        child2.get(0).get(0).put("CHANGE", "TRUE");
        adapter.notifyDataSetChanged();*/
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

}

Options Activity
Code:
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.PrintWriter;
import java.net.Socket;

public class OptionsActivity extends Activity implements OnClickListener{

    private PrintWriter printwriter;
    private EditText textField;
    private String message;
    private String pieceSelected;

    TextView response;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_options);

        textField = (EditText) findViewById(R.id.name_editText);

        // Set up click listeners for all the buttons
        View saveButton = findViewById(R.id.saveOptions_button);
        //saveButton.setOnClickListener(this);

        View backOptionsButton = findViewById(R.id.backOptions_button);
        backOptionsButton.setOnClickListener(this);

        View choosePieceButton = findViewById(R.id.choosePiece_button);
        choosePieceButton.setOnClickListener(this);

        saveButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                message = textField.getText().toString(); // get the text message on the text field

                message+=";";
                message+=pieceSelected;

                MainActivity.tcpClient.sendMessage(message);
            }
        });
    }

    //@Override
    public void onClick(View v) {
        if (v.getId() == R.id.backOptions_button) {
            finish();
        } else if (v.getId() == R.id.saveOptions_button) {

        } else if (v.getId() == R.id.choosePiece_button) {
            Intent i = new Intent(this, GridViewPiecesActivity.class);
            startActivityForResult(i,1);
        }

    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1) {
            if(resultCode == RESULT_OK){
                pieceSelected=data.getStringExtra("edittextvalue");
            }
        }
    }

}
 
Thanks for helping me. Your answer was very helpful.

I need your help again.

Could anyone tell me how can I get access on server message response at MainActivity?

Thanks
 
Hi,

Imagine somewhere in ManyActivity I send a message to server.

Code:
tcpClient.sendMessage("something");

Then, how could I get the server response in that Activity?

Thanks
 
Your TcpClient class has a constructor which takes a listener parameter. The method messageReceived() is called on the listener whenever a message is received by the TcpClient.

Why not create an instance of the TcpClient, and pass in a listener?
 
Thanks for helping me.

Imagine I'm at MainActivity and that activity has a button. Then I want to jump to another activty onClick event of that button, based on server response.

Something like that: if server response is "yes" I start a new activty, otherwise no.

Code:
@Override
public void onClick(View v) {
    Intent i;
    switch (v.getId()) {
        case R.id.playNow_button:
            tcpClient.sendMessage("")
            if (response.equalsIgnoreCase("yes")) {
                i = new Intent(this, SettingsActivity.class);
                startActivity(i);
                break;
            }

Thanks
 
So the messageReceived() method of your OnMessageReceived() method would be the place to put this code

Code:
if (response.equalsIgnoreCase("yes")) {
                i = new Intent(this, SettingsActivity.class);
                startActivity(i);
            }
 
Hi again,

I need your help again, please.

As you can see above I made a server that support many clients, each one with a thread.

Until now clients are sending messages to the server and then do something based on server response.

But now I need that server send a message to a specific client and I don't know how.

Could you help me please?

Thanks
 
But isn't there a one to one connection between client and server?

You create a new TcpClient object to communicate with the server. When the server detects an incoming client request, then a new thread will be created to handle it.

You call ServerSocket.accept(), which just blocks until an incoming connection request is detected.
 
Last edited by a moderator:
But what changes have I have to do in order to server could send a message to a specific client without a request from him?

Thanks

Well the client must initiate the connection, not the other way round.

Once the server has received an initial message from the client, you could then possibly hold the connection open to push messages to the client from the server.
 
Back
Top Bottom