Refer to the previous Android client example to send message to Java server on Raspberry Pi. The client Android Client connect To Java Server, and send something then close socket. This example show how Android Client connect to Java Server (run on raspberry Pi) and keep connected, and send to and receive from Server.
For the Server side, it's Java Echo Server to send back the received data to the sender.
Please notice:
Suppose the Disconnect button is used to disconnect from server once clicked. In this example, it cannot actually. Because the code bufferedReader.readLine() in ClientThread.java will block the program. The Disconnect request will wait until anything received to return from bufferedReader.readLine().
Create ClientThread.java to handle network related job in background thread.
package com.blogspot.android_er.androidclient;
import android.os.Message;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ClientThread extends Thread{
String dstAddress;
int dstPort;
private boolean running;
MainActivity.ClientHandler handler;
Socket socket;
PrintWriter printWriter;
BufferedReader bufferedReader;
public ClientThread(String addr, int port, MainActivity.ClientHandler handler) {
super();
dstAddress = addr;
dstPort = port;
this.handler = handler;
}
public void setRunning(boolean running){
this.running = running;
}
private void sendState(String state){
handler.sendMessage(
Message.obtain(handler,
MainActivity.ClientHandler.UPDATE_STATE, state));
}
public void txMsg(String msgToSend){
if(printWriter != null){
printWriter.println(msgToSend);
}
}
@Override
public void run() {
sendState("connecting...");
running = true;
try {
socket = new Socket(dstAddress, dstPort);
sendState("connected");
OutputStream outputStream = socket.getOutputStream();
printWriter = new PrintWriter(outputStream, true);
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader =
new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(inputStreamReader);
while(running){
//bufferedReader block the code
String line = bufferedReader.readLine();
if(line != null){
handler.sendMessage(
Message.obtain(handler,
MainActivity.ClientHandler.UPDATE_MSG, line));
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bufferedReader != null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(printWriter != null){
printWriter.close();
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
handler.sendEmptyMessage(MainActivity.ClientHandler.UPDATE_END);
}
}
MainActivity.java
package com.blogspot.android_er.androidclient;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
EditText editTextAddress, editTextPort, editTextMsg;
Button buttonConnect, buttonDisconnect, buttonSend;
TextView textViewState, textViewRx;
ClientHandler clientHandler;
ClientThread clientThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText) findViewById(R.id.address);
editTextPort = (EditText) findViewById(R.id.port);
editTextMsg = (EditText) findViewById(R.id.msgtosend);
buttonConnect = (Button) findViewById(R.id.connect);
buttonDisconnect = (Button) findViewById(R.id.disconnect);
buttonSend = (Button)findViewById(R.id.send);
textViewState = (TextView)findViewById(R.id.state);
textViewRx = (TextView)findViewById(R.id.received);
buttonDisconnect.setEnabled(false);
buttonSend.setEnabled(false);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonDisconnect.setOnClickListener(buttonDisConnectOnClickListener);
buttonSend.setOnClickListener(buttonSendOnClickListener);
clientHandler = new ClientHandler(this);
}
View.OnClickListener buttonConnectOnClickListener =
new View.OnClickListener() {
@Override
public void onClick(View arg0) {
clientThread = new ClientThread(
editTextAddress.getText().toString(),
Integer.parseInt(editTextPort.getText().toString()),
clientHandler);
clientThread.start();
buttonConnect.setEnabled(false);
buttonDisconnect.setEnabled(true);
buttonSend.setEnabled(true);
}
};
View.OnClickListener buttonDisConnectOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(clientThread != null){
clientThread.setRunning(false);
}
}
};
View.OnClickListener buttonSendOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(clientThread != null){
String msgToSend = editTextMsg.getText().toString();
clientThread.txMsg(msgToSend);
}
}
};
private void updateState(String state){
textViewState.setText(state);
}
private void updateRxMsg(String rxmsg){
textViewRx.append(rxmsg + "\n");
}
private void clientEnd(){
clientThread = null;
textViewState.setText("clientEnd()");
buttonConnect.setEnabled(true);
buttonDisconnect.setEnabled(false);
buttonSend.setEnabled(false);
}
public static class ClientHandler extends Handler {
public static final int UPDATE_STATE = 0;
public static final int UPDATE_MSG = 1;
public static final int UPDATE_END = 2;
private MainActivity parent;
public ClientHandler(MainActivity parent) {
super();
this.parent = parent;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case UPDATE_STATE:
parent.updateState((String)msg.obj);
break;
case UPDATE_MSG:
parent.updateRxMsg((String)msg.obj);
break;
case UPDATE_END:
parent.clientEnd();
break;
default:
super.handleMessage(msg);
}
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:orientation="vertical"
tools:context="com.blogspot.android_er.androidclient.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<EditText
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="192.168."
android:hint="dstAddress" />
<EditText
android:id="@+id/port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="8000"
android:hint="dstPort" />
<Button
android:id="@+id/connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connect"/>
<Button
android:id="@+id/disconnect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Disconnect"/>
<TextView
android:id="@+id/state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="un-initiated"
android:textSize="20dp"/>
<EditText
android:id="@+id/msgtosend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="msg to send..." />
<Button
android:id="@+id/send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send"/>
<TextView
android:id="@+id/received"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>
uses-permission of "android.permission.INTERNET" is needed in AndroidManifest.xml
Download the files .
Thank you very much for the andriod side coding.but what is the coding on Raspberry's side in that javaserver program ? Being a beginner, that would be very helpful :)
ReplyDeletehi thk you very much for this wonderful video . I managed to do everything as exactly written. i can connect to the server but as soon as I press send button. the android app stopped and close itself. am i missing something. please help me
ReplyDeletetring to build the above i ran into
ReplyDeleteandroid.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
to correct this please add the following 2 lines below
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
setContentView(R.layout.activity_main);