The app has MainActivity(contains an EditText and a Button) and DisplayActivity(contains a single TextView)The user enters a message in the EditText and presses the send button. The message string from the EditText gets sent to the server. Then starts a new intent to DisplayActivity. DisplayActivity will read data from the server with readLine(), and set TextView from the data received from the server.
activity_main.xml has a EditText with id="#+id/message_textView" and Button with id="#+id/send_button". DisplayActivity has android:id="#+id/displayTextView".
My code to send data to the server works, but when I try to read data from the server, readline() just stops there and sits there forever.
Android app has MainActivity and DisplayActivity class.
I run the server code in eclipse.
Server code.
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.net.*;
import java.io.*;
public class MyServer {
public static void main(String[] args) throws IOException {
int portNumber = 4442;
System.out.println("Starting server..");
try {
while(true) {
ServerSocket serverSocket =
new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String message = in.readLine();
System.out.println(message);//Just print to console, to test if server got message
out.println(message);
serverSocket.close();
clientSocket.close();
// out.close();
// in.close();
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
MainActivity
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
static Socket client;
private PrintWriter printWriter;
private EditText messageET;
private Button sendButton;
private String message;
static String hostIP = "10.0.2.2";
static int port = 4442;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
messageET = findViewById(R.id.message_textView);
sendButton = findViewById(R.id.send_button);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
message = messageET.getText().toString();
messageET.setText("");
MyTask myTask = new MyTask();
myTask.execute();
Intent intent = new Intent(getApplicationContext(), DisplayActivity.class);
startActivity(intent);
}
});
}
class MyTask extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... strings) {
try
{
client = new Socket(hostIP, port);
printWriter = new PrintWriter(client.getOutputStream(), true);
//printWriter.write(message);
printWriter.println(message);
//printWriter.flush();
printWriter.close();
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
return null;
}
}
}
DisplayActivity
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class DisplayActivity extends AppCompatActivity {
//final String TAG = "displayactivitylog";
private Socket socket;
private BufferedReader bufferedReader;
private TextView displayTV;
private String msgReceived = null;
String hostIP = "10.0.2.2";
int port = 4442;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display);
displayTV = findViewById(R.id.displayTextView);
ReadTask readTask = new ReadTask();
readTask.execute();
}
class ReadTask extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... strings) {
String result = "";
try
{
//create a new socket and attempt to read from it
socket = new Socket(hostIP,port);
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//*****the app stops on this line, and nothing happens after*****
msgReceived = bufferedReader.readLine();
//************************************
// while((msgReceived = bufferedReader.readLine()) != null){
// result += msgReceived;
// }
bufferedReader.close();
socket.close();
}catch(IOException e)
{
e.printStackTrace();
}
return result;
}
//update the TextView with the message from the server
#Override
protected void onPostExecute(String s) {
displayTV.setText(s);
super.onPostExecute(s);
}
}
}
When i run debugger, it literally just stops in DisplayActivity.java on msgReceived = bufferedReader.readLine() in the doInBackground() method and gives no error.
My server starts fine and when I send data from my app to the server, on eclipse it prints out what was sent(and sometimes null for some reason).
---------------SOLUTION---------------
Question was answered by green apps, but basically the server class expects to read something when a connection first opens, and then send out data. However in ReadTask, all it does is try to read data from the server(but it should send data first, then read from it)
Updated code.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private EditText messageET;
private Button sendButton;
static String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
messageET = findViewById(R.id.message_textView);
sendButton = findViewById(R.id.send_button);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
message = messageET.getText().toString();
messageET.setText("");
Intent intent = new Intent(getApplicationContext(), DisplayActivity.class);
startActivity(intent);
}
});
}
}
DisplayActivity.java
public class DisplayActivity extends AppCompatActivity {
private Socket socket;
private PrintWriter printWriter;
private BufferedReader bufferedReader;
private TextView displayTV;
private String msgReceived = null;
String hostIP = "10.0.2.2";
int port = 4442;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display);
displayTV = findViewById(R.id.displayTextView);
ReadTask readTask = new ReadTask();
readTask.execute();
}
class ReadTask extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... strings) {
String result = "";
try
{
//create a new socket and attempt to write to it first then read from it
socket = new Socket(hostIP,port);
//add data to the server
printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println(MainActivity.message);
//get a stream, to be able to read data from the server
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
msgReceived = bufferedReader.readLine();
displayTV.setText(msgReceived);
//close the socket connections
printWriter.close();
bufferedReader.close();
socket.close();
}catch(IOException e)
{
e.printStackTrace();
}
return result;
}
}
}
You have two clientsocketss. And two serversockets.
Which is a very strange approach.
The first client sends a line and closes the connection. This works ok as the server tries to read that line and does. Both then close.
Then you start the second client. This one connects to a new serversocket. But this client directly tries to read a line. As the server also tries to read a line from this new client both will wait for eternity on readLine().
Related
Hello I am trying to write simple client-server application in android.Here is my code for the client.
package com.sudarshan.client;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.AsyncTask;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity {
private Socket client;
private PrintWriter printwriter;
private EditText textField;
private Button button;
private String messsage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
textField = (EditText) findViewById(R.id.editText1); // reference to the text field
button = (Button) findViewById(R.id.button1); // reference to the send button
// Button press event listener
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
messsage = textField.getText().toString(); // get the text message on the text field
textField.setText(""); // Reset the text field to blank
SendMessage sendMessageTask = new SendMessage();
sendMessageTask.execute();
}
});
}
private class SendMessage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
client = new Socket("10.0.2.2", 4444); // connect to the server
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write(messsage); // write the message to output stream
printwriter.flush();
printwriter.close();
client.close(); // closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
#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, menu);
return true;
}
}
Here is the code for server
package com.sudarshan.server;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
private static ServerSocket serverSocket;
private static Socket clientSocket;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
serverSocket = new ServerSocket(4444); // Server socket
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
}
System.out.println("Server started. Listening to the port 4444");
while (true) {
try {
clientSocket = serverSocket.accept(); // accept the client connection
inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader); // get the client message
message = bufferedReader.readLine();
System.out.println(message);
inputStreamReader.close();
clientSocket.close();
} catch (IOException ex) {
System.out.println("Problem in message reading");
}
}
}
}
The server code crashes.It gives a error as "java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sudarshan.server/com.sudarshan.server.MainActivity}: android.os.NetworkOnMainThreadException".
What am i doing wrong?
Solved.
"android.os.NetworkOnMainThreadException" means that Network related tasks are not to be done on main thread directly ie. Activity Class.So, need to make a thread under main thread then do the work.
I'm creating an an Android Application which connects to Python Server and send UP and DOWN command and a Python code response like: light is ON and Light is Off.
Although I add a button to Android application which sends data to Python and a Python server sends back some string or a function to the Android app which shows up in Android TextView (I need to run a function on Raspberry and get the result back to Android in textView).
enter code here
package com.example.myapplication;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class MainActivity extends AppCompatActivity {
Button btnUp;
Button btnDown;
Button rButton;
EditText txtAddress;
Socket myAppSocket = null;
public static String wifiModuleIp = "";
public static int wifiModulePort = 0;
public static String CMD = "0";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnUp = (Button) findViewById(R.id.btnUP);
btnDown = (Button) findViewById(R.id.btnDown);
rButton = (Button) findViewById(R.id.rButton);
txtAddress = (EditText) findViewById(R.id.ipAddress);
btnUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getIPandPort();
CMD = "UP";
Soket_AsyncTask cmd_increase_servo = new Soket_AsyncTask();
cmd_increase_servo.execute();
}
});
btnDown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getIPandPort();
CMD = "DOWN";
Soket_AsyncTask cmd_decrease_servo = new Soket_AsyncTask();
cmd_decrease_servo.execute();
}
});
rButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getIPandPort();
CMD = "VIEW";
Socket_Received cmd_received_pi = new Socket_Received();
cmd_received_pi.execute();
}
});
}
public void getIPandPort() {
String iPandPort = txtAddress.getText().toString();
String temp[] = iPandPort.split(":");
wifiModuleIp = temp[0];
wifiModulePort = Integer.valueOf(temp[1]);
//Log.d("MYTEST","IP String" +iPandPort);
//Log.d("MY TEST","IP:"+wifiModuleIp);
// Log.d("MY TEST","PORT"+wifiModulePort);
}
public class Soket_AsyncTask extends AsyncTask<Void, Void, Void> {
Socket socket;
protected Void doInBackground(Void... params) {
try {
InetAddress inetAdress = InetAddress.getByName(MainActivity.wifiModuleIp);
socket = new java.net.Socket(inetAdress, MainActivity.wifiModulePort);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeBytes(CMD);
dataOutputStream.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
public class Socket_Received extends AsyncTask<String, Void, Void> {
ServerSocket cScoket;
Socket socket;
//public TextView textView;
private DataInputStream in;
#SuppressLint("WrongThread")
protected Void doInBackground(String... params) {
try {
cScoket = new ServerSocket(MainActivity.wifiModulePort);
socket = cScoket.accept();
in = new DataInputStream(socket.getInputStream());
InputStreamReader reader = new InputStreamReader(in);
BufferedReader br = new BufferedReader(reader);
final TextView textView = (TextView)findViewById(R.id.txtView);
textView.setText(br.toString());
socket.close();
in.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
My Python code here:
enter code here
import lighton
from socket import *
from time import ctime
import time
lighton.setUP()
ctrCmd = ['UP','DOWN','VIEW']
HOST = ''
PORT = 5555
BUFSIZE = 1024
ADDR = (HOST,PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
while True:
tcpCliSock,addr = tcpSerSock.accept()
time.sleep(.05)
data = ''
data = tcpCliSock.recv(BUFSIZE).decode()
if not data:
print("there is no data")
break
if data == ctrCmd[0]:
lighton.ledOn()
if data == ctrCmd[1]:
lighton.ledOff()
if data == ctrCmd[2]:
r="hello world"
tcpCliSock.send(r.encode())
tcpSerSock.close();
My Python light on class code here:
import time
def setUP():
print("Setting up...")
def ledOn():
print("led is on")
def ledOff():
print("led is off")
if __name__ == '__main__':
setup()
URL = http://troyka.esy.es/numberofrows.php
if you put that in your browser you'l get a number (currently it's 9)
I'm trying to pull that number to my android app and display it on a textview
I've tried this method but it shows me nothing on the emulator
internet and network permission are set on manifest
textview id = "textView"
What am I doing wrong?
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
public class MainActivity extends Activity {
public static String ans;
private TextView T1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
T1 = new TextView(this);
T1 = (TextView) findViewById(R.id.textView);
T1.setText(ans);
}
public String getDATA() throws IOException {
String fullString = "";
URL url = new URL("http://troyka.esy.es/numberofrows.php");
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = reader.readLine()) != null) {
fullString += line;
}
reader.close();
return fullString;
}
public void setAns() throws IOException {
ans = getDATA();
}
}
Try this answer please:
First, create an AsyncTask class like this to do the actual HTTP request for you outside the android main thread:
public class FetchColumnAsync extends AsyncTask<String, Void, String>
{
private Context mContext;
public FetchColumnAsync( Context ctx){
this.mContext = ctx;
}
protected String doInBackground(String... urls)
{
String fullString = "";
try{
URL url = new URL(urls[0]);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = reader.readLine()) != null) {
fullString += line;
}
reader.close();
}catch(Exception e ){
e.getMessage();
}
return fullString;
}
#Override
protected void onPostExecute(String value){
try{
((OnValueFetchedListener) mContext).onValueFetched(value);
}catch(ClassCastException e){}
}
public interface OnValueFetchedListener{
void onValueFetched(String columns);
}
}
Then in your activity class, implement the above interface like this;
public class MainActivity extends Activity implements FetchColumnAsync.OnValueFetchedListener{
public static String ans;
private TextView T1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
T1 = (TextView) findViewById(R.id.textView);
//missing piece of code here
new FetchColumnAsync(this).execute("http://troyka.esy.es/numberofrows.php");
}
#Override
public void onValueFetched(String value){
T1.setText(value);
}
}
I'm trying to connect to a servlet in localhost from my Android Emulator.
I created a project in Eclipse named SimpleHttpGetRequest with an activity named "HttpGetServletActivity".
I created in NetBeans a project named "HttpGetRequest" containing a servlet.
The code in my "HttpGetServletActivity" activity is :
package com.mobdev.simplehttprequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class HttpGetServletActivity extends Activity implements OnClickListener {
Button button;
TextView outputText;
public static final String URL = "http://10.0.2.2:8080/HttpGetRequest/HelloWorldServlet";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewsById();
button.setOnClickListener(this);
}
private void findViewsById() {
button = (Button) findViewById(R.id.button);
outputText = (TextView) findViewById(R.id.outputTxt);
}
public void onClick(View view) {
GetXMLTask task = new GetXMLTask();
task.execute(new String[]{ URL });
}
private class GetXMLTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String output = null;
for (String url : urls) {
output = getOutputFromUrl(url);
}
return output;
}
private String getOutputFromUrl(String url) {
StringBuffer output = new StringBuffer("");
try {
InputStream stream = getHttpConnection(url);
BufferedReader buffer = new BufferedReader(
new InputStreamReader(stream));
String s = "";
while ((s = buffer.readLine()) != null)
output.append(s);
} catch (IOException e1) {
e1.printStackTrace();
}
return output.toString();
}
// Makes HttpURLConnection and returns InputStream
private InputStream getHttpConnection(String urlString)
throws IOException {
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
try {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("get");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return stream;
}
#Override
protected void onPostExecute(String output) {
outputText.setText(output);
}
}
}
The source code of my servlet is :
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloWorldServlet extends HttpServlet {
public HelloWorldServlet() {
super();
}
#Override
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("Hello Android !!!!");
}
}
I deployed my servlet in Apache server (i'm using xampp);
I added permission for network connection
When I run my App and click on the button, the App crashes, and I don't know why !!
Can anybody help me, please ? Im' stuck.
I tried :
Wifi connection : I did run my App on a real device, instead of "10.0.2.2" I put the ip adress of my PC but it doesn't work ;
Access to project HttpGetrequest from Android Emulator browser, it worked ;
Can anyone let me know what is wrong in the below code.. Why is it not executing the while loop block?
I have the necessary permissions in the manifest file.
public class MainActivity extends Activity {
static TextView t;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t=(TextView)findViewById(R.id.txt);
NetConnect th=new NetConnect();
th.start();
}
public class NetConnect extends Thread {
public void run(){
try{
runOnUiThread(new Runnable(){public void run(){t.append("Thread start...");}});
Socket client = new Socket("time-b.nist.gov", 13);
BufferedReader in =new BufferedReader(new InputStreamReader(client.getInputStream()));
String str;
while((str=in.readLine())!=null)
t.append(str);
}catch(Exception e){
Log.e("Internet:",e.toString());
}
}
}
There seems to be a problem with "time-b.nist.gov". I tried the following simple socket example in a java project (to simplify against creating an Android project):
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TestSocketClass {
public static void main(String[] args) {
String hostname = "time-b.nist.gov";
try {
Socket theSocket = new Socket(hostname, 13);
InputStream timeStream = theSocket.getInputStream();
StringBuffer time = new StringBuffer();
int c;
while ((c = timeStream.read()) != -1)
time.append((char) c);
String timeString = time.toString().trim();
System.out.println("It is " + timeString + " at " + hostname);
} // end try
catch (UnknownHostException ex) {
System.err.println(ex);
} catch (IOException ex) {
System.err.println(ex);
}
}
}
Nothing returned if String hostname = "time-b.nist.gov";:
It is at time-b.nist.gov
but if I change it to String hostname = "time.nist.gov"; I get:
It is 56438 13-05-26 11:49:57 50 0 0 809.9 UTC(NIST) * at
time.nist.gov