On Being a Duplicate: Please note that I have acknowledged other Q&As (Thread UI) but my case is different as I have tried to use the solution but it doesn't work at all instances (as it works for writing but doesn't for reading.
Updated: I know exactly what is going wrong please read the bold My Question part I'm trying to make an Android Socket Client that connects to a Java server via WiFi.The final client will send and receive commands and logs as there will be a textbox that user can write SQL commands in it and by hitting a button command will be sent from the app to the Desktop server and show the log in another textbox.
so far I have been trying to use This Answer from another question to make that Client, and adding following lines in the TCP client.
Scanner in = new Scanner(socket.getInputStream());//in doInBackground
//also changed send method a little
public String send(String command)
{
if ( connected ){
out.println(command);
out.flush();
String back = in.nextLine().toString();
return back;
}
return "not Connected";
}
The connection is made successfully and the send method does send the command while server receives it.but the String that server writes back throw the mentioned exception in the title despite the fact that I am using the AsyncTask.
My Question
Why Scanner throws this exception while PrintWriter works correctly ?
Main Activity
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
EditText serverIP, servMsg;
String ip, serverOut;
Button connectBtn;
TcpClient tcpClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serverIP = (EditText) findViewById(R.id.serverIP);
connectBtn = (Button) findViewById(R.id.connectBtn);
servMsg = (EditText) findViewById(R.id.servMsg);
}
public void onConnectBtn(View view){
try{
ip = serverIP.getText().toString();
tcpClient = new TcpClient();
tcpClient.connect(getApplicationContext(), ip, 8082);
serverOut = tcpClient.send("HELLO FROM cat:123");
servMsg.setText(serverOut);
tcpClient.disconnect(getApplicationContext());
}
catch (Exception e){
Toast.makeText(getApplicationContext(),
"Exception on runnning thread: " + e.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}
@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);
}
}
TCP Client
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
public class TcpClient {
private static final String TAG = TcpClient.class.getSimpleName();
private Socket socket;
private PrintWriter out;
private Scanner in;
private boolean connected;
public TcpClient() {
socket = null;
out = null;
connected = false;
}
public void connect(Context context, String host, int port) {
new ConnectTask(context).execute(host, String.valueOf(port));
}
private class ConnectTask extends AsyncTask<String, Void, Void> {
private Context context;
public ConnectTask(Context context) {
this.context = context;
}
@Override
protected void onPreExecute() {
showToast(context, "Connecting..");
super.onPreExecute();
}
@Override
protected void onPostExecute(Void result) {
if (connected) {
showToast(context, "Connection successful");
}
super.onPostExecute(result);
}
private String host;
private int port;
@Override
protected Void doInBackground(String... params) {
try {
String host = params[0];
int port = Integer.parseInt(params[1]);
socket = new Socket(host, port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new Scanner(socket.getInputStream());
} catch (UnknownHostException e) {
showToast(context, "Don't know about host: " + host + ":" + port);
Log.e(TAG, e.getMessage());
} catch (IOException e) {
showToast(context, "Couldn't get I/O for the connection to: " + host + ":" + port);
Log.e(TAG, e.getMessage());
}
connected = true;
return null;
}
}
public void disconnect(Context context) {
if (connected) {
try {
out.close();
socket.close();
connected = false;
} catch (IOException e) {
showToast(context, "Couldn't get I/O for the connection");
Log.e(TAG, e.getMessage());
}
}
}
/**
* Send command to a Pure Data audio engine.
*/
public String send(String command)
{
if ( connected ){
out.println(command);
out.flush();
String back = in.nextLine().toString();
return back;
}
return "not Connected";
}
private void showToast(final Context context, final String message) {
new Handler(context.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
});
}
}
Also the Layout right now consist of two TextEdits one in which user types IP of the computer(which I checked with correct IPs) and the second one is going to show Server response.