Showing posts with label Android code sample: Networking. Show all posts
Showing posts with label Android code sample: Networking. Show all posts

Android Datagram/UDP Server example


I posted "Java Datagram/UDP Server and Client, run on raspberry Pi" on my another blogspot. And last post show "Android Datagram/UDP Client example". This post show a Datagram/UDP Server run on Android.


MainActivity.java
package com.blogspot.android_er.androidudpserver;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Date;
import java.util.Enumeration;

public class MainActivity extends AppCompatActivity {

private final static String TAG = MainActivity.class.getSimpleName();

TextView infoIp, infoPort;
TextView textViewState, textViewPrompt;

static final int UdpServerPORT = 4445;
UdpServerThread udpServerThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
infoIp = (TextView) findViewById(R.id.infoip);
infoPort = (TextView) findViewById(R.id.infoport);
textViewState = (TextView)findViewById(R.id.state);
textViewPrompt = (TextView)findViewById(R.id.prompt);

infoIp.setText(getIpAddress());
infoPort.setText(String.valueOf(UdpServerPORT));
}

@Override
protected void onStart() {
udpServerThread = new UdpServerThread(UdpServerPORT);
udpServerThread.start();
super.onStart();
}

@Override
protected void onStop() {
if(udpServerThread != null){
udpServerThread.setRunning(false);
udpServerThread = null;
}

super.onStop();
}

private void updateState(final String state){
runOnUiThread(new Runnable() {
@Override
public void run() {
textViewState.setText(state);
}
});
}

private void updatePrompt(final String prompt){
runOnUiThread(new Runnable() {
@Override
public void run() {
textViewPrompt.append(prompt);
}
});
}

private class UdpServerThread extends Thread{

int serverPort;
DatagramSocket socket;

boolean running;

public UdpServerThread(int serverPort) {
super();
this.serverPort = serverPort;
}

public void setRunning(boolean running){
this.running = running;
}

@Override
public void run() {

running = true;

try {
updateState("Starting UDP Server");
socket = new DatagramSocket(serverPort);

updateState("UDP Server is running");
Log.e(TAG, "UDP Server is running");

while(running){
byte[] buf = new byte[256];

// receive request
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet); //this code block the program flow

// send the response to the client at "address" and "port"
InetAddress address = packet.getAddress();
int port = packet.getPort();

updatePrompt("Request from: " + address + ":" + port + "\n");

String dString = new Date().toString() + "\n"
+ "Your address " + address.toString() + ":" + String.valueOf(port);
buf = dString.getBytes();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);

}

Log.e(TAG, "UDP Server ended");

} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(socket != null){
socket.close();
Log.e(TAG, "socket.close()");
}
}
}
}

private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();

if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}

}

}

} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}

return ip;
}
}


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.androidudpserver.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" />

<TextView
android:id="@+id/infoip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic" />

<TextView
android:id="@+id/infoport"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic" />

<TextView
android:id="@+id/state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="un-initiated"
android:textSize="20dp"/>

<TextView
android:id="@+id/prompt"
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

Remark about life-cycle:
In this example, the DatagramSocket server is run in background thread. I haven't handle the life-cycle very well (Actually I don't think any application will have UI like this example). Consider the cases:

Case One:
- Start the app, the activity display on screen and the DatagramSocket opened in associated thread.
- the code socket.receive(packet) block the program flow, so the thread stay here and waiting data request.
- Exit the app. It will set running to false, to request the thread to stop. But the thread is blocked in socket.receive(packet), so it's still running.
- Restart the app, the new thread cannot open the DatagramSocket, because it's still held by old thread.
- Client send a request, the DatagramSocket server response the request and exit socket.receive(packet), and check running and exit.
- In this case, the current activity and associated thread have no DatagramSocket opened!

Case Two:
- Start the app, the activity display on screen and the DatagramSocket opened in associated thread.
- the code socket.receive(packet) block the program flow, so the thread stay here and waiting data request.
- Exit the app. It will set running to false, to request the thread to stop. But the thread is blocked in socket.receive(packet), so it's still running.
- Client send a request, the DatagramSocket server response the request and exit socket.receive(packet), and check running and exit.
- Restart the app, and open the DatagramSocket.
- In this case, the current activity and associated thread can open DatagramSocket and work as expected.


download filesDownload the files .

Android Datagram/UDP Client example


I posted "Java Datagram/UDP Server and Client, run on raspberry Pi" on my another blogspot. It's the Android version of the client.


MainActivity.java
package com.blogspot.android_er.androidudpclient;

import android.os.Handler;
import android.os.Message;
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;

public class MainActivity extends AppCompatActivity {

EditText editTextAddress, editTextPort;
Button buttonConnect;
TextView textViewState, textViewRx;

UdpClientHandler udpClientHandler;
UdpClientThread udpClientThread;

@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);
buttonConnect = (Button) findViewById(R.id.connect);
textViewState = (TextView)findViewById(R.id.state);
textViewRx = (TextView)findViewById(R.id.received);

buttonConnect.setOnClickListener(buttonConnectOnClickListener);

udpClientHandler = new UdpClientHandler(this);
}

View.OnClickListener buttonConnectOnClickListener =
new View.OnClickListener() {

@Override
public void onClick(View arg0) {

udpClientThread = new UdpClientThread(
editTextAddress.getText().toString(),
Integer.parseInt(editTextPort.getText().toString()),
udpClientHandler);
udpClientThread.start();

buttonConnect.setEnabled(false);
}
};

private void updateState(String state){
textViewState.setText(state);
}

private void updateRxMsg(String rxmsg){
textViewRx.append(rxmsg + "\n");
}

private void clientEnd(){
udpClientThread = null;
textViewState.setText("clientEnd()");
buttonConnect.setEnabled(true);

}

public static class UdpClientHandler 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 UdpClientHandler(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);
}

}
}
}


UdpClientThread.java
package com.blogspot.android_er.androidudpclient;

import android.os.Message;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class UdpClientThread extends Thread{

String dstAddress;
int dstPort;
private boolean running;
MainActivity.UdpClientHandler handler;

DatagramSocket socket;
InetAddress address;

public UdpClientThread(String addr, int port, MainActivity.UdpClientHandler 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.UdpClientHandler.UPDATE_STATE, state));
}

@Override
public void run() {
sendState("connecting...");

running = true;

try {
socket = new DatagramSocket();
address = InetAddress.getByName(dstAddress);

// send request
byte[] buf = new byte[256];

DatagramPacket packet =
new DatagramPacket(buf, buf.length, address, dstPort);
socket.send(packet);

sendState("connected");

// get response
packet = new DatagramPacket(buf, buf.length);


socket.receive(packet);
String line = new String(packet.getData(), 0, packet.getLength());

handler.sendMessage(
Message.obtain(handler, MainActivity.UdpClientHandler.UPDATE_MSG, line));

} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(socket != null){
socket.close();
handler.sendEmptyMessage(MainActivity.UdpClientHandler.UPDATE_END);
}
}

}
}


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.androidudpclient.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="4445"
android:hint="dstPort" />
<Button
android:id="@+id/connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connect"/>

<TextView
android:id="@+id/state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="un-initiated"
android:textSize="20dp"/>

<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 filesDownload the files .

Next:
Android Datagram/UDP Server example

Android client example 2, communicate with Java Server run on Raspberry Pi


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 filesDownload the files .

Android client to send message to Java server on Raspberry Pi


It's a Java client and server exercise in my another blogspot HelloraspberryPi. The client connect to server and send something, the server simple print the received message and close.

It's Android version of the client, to connect to server and send something.


MainActivity.java
package com.blogspot.android_er.androidclient;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class MainActivity extends AppCompatActivity {

EditText editTextAddress, editTextPort, editTextMsg;
Button buttonConnect;

@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);

buttonConnect.setOnClickListener(buttonConnectOnClickListener);
}

View.OnClickListener buttonConnectOnClickListener =
new View.OnClickListener() {

@Override
public void onClick(View arg0) {
MyClientTask myClientTask = new MyClientTask(
editTextAddress.getText().toString(),
Integer.parseInt(editTextPort.getText().toString()));
myClientTask.execute(editTextMsg.getText().toString());
}
};

public class MyClientTask extends AsyncTask<String, Void, Void> {

String dstAddress;
int dstPort;
String response;

MyClientTask(String addr, int port) {
dstAddress = addr;
dstPort = port;
}

@Override
protected Void doInBackground(String... params) {
try {
Socket socket = new Socket(dstAddress, dstPort);

OutputStream outputStream = socket.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.print(params[0]);

socket.close();

} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

}
}


layout/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:hint="dstAddress" />
<EditText
android:id="@+id/port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="dstPort" />
<EditText
android:id="@+id/msgtosend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="msg to send..." />
<Button
android:id="@+id/connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connect and send..."/>

</LinearLayout>


uses-permission of "android.permission.INTERNET" is needed in AndroidManifest.xml

The Java code of the server side, refer to "Java Network exercise: client and server - client send something to server".

The next example "Android client example 2, communicate with Java Server run on Raspberry Pi" show how Android Client connect to Java Server (run on raspberry Pi) and keep connected, and send to and receive from Server.

File transfer via Socket, between Android devices

This example show how to transfer file between Android devices, via Socket.

In server side, it start a Thread to run a ServerSocket and wait for connection. Once connected, start another Thread to send file.

In client side, start a Thread to connect to server and download file.

In this example, the file to send and receive are fixed test.txt in external storage.



Server Side:

MainActivity.java
package com.example.androidsocketfiletransferserver;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Enumeration;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

TextView infoIp, infoPort;

static final int SocketServerPORT = 8080;
ServerSocket serverSocket;

ServerSocketThread serverSocketThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
infoIp = (TextView) findViewById(R.id.infoip);
infoPort = (TextView) findViewById(R.id.infoport);

infoIp.setText(getIpAddress());

serverSocketThread = new ServerSocketThread();
serverSocketThread.start();
}

@Override
protected void onDestroy() {
super.onDestroy();

if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();

if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}

}

}

} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}

return ip;
}

public class ServerSocketThread extends Thread {

@Override
public void run() {
Socket socket = null;

try {
serverSocket = new ServerSocket(SocketServerPORT);
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
infoPort.setText("I'm waiting here: "
+ serverSocket.getLocalPort());
}});

while (true) {
socket = serverSocket.accept();
FileTxThread fileTxThread = new FileTxThread(socket);
fileTxThread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

}

public class FileTxThread extends Thread {
Socket socket;

FileTxThread(Socket socket){
this.socket= socket;
}

@Override
public void run() {
File file = new File(
Environment.getExternalStorageDirectory(),
"test.txt");

byte[] bytes = new byte[(int) file.length()];
BufferedInputStream bis;
try {
bis = new BufferedInputStream(new FileInputStream(file));
bis.read(bytes, 0, bytes.length);
OutputStream os = socket.getOutputStream();
os.write(bytes, 0, bytes.length);
os.flush();
socket.close();

final String sentMsg = "File sent to: " + socket.getInetAddress();
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
Toast.makeText(MainActivity.this,
sentMsg,
Toast.LENGTH_LONG).show();
}});

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
}
}

activity_main.xml
<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:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.androidsocketfiletransferserver.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" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="File Transfer Server"
android:textStyle="bold" />

<TextView
android:id="@+id/infoport"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic" />

<TextView
android:id="@+id/infoip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic" />

</LinearLayout>

Add permission of "android.permission.INTERNET" and "android.permission.READ_EXTERNAL_STORAGE" to AndroidManifest.xml.

download filesDownload the files.


Client Side:

MainActivity.java
package com.example.androidsocketfiletransferclient;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Bundle;
import android.os.Environment;

public class MainActivity extends ActionBarActivity {

EditText editTextAddress;
Button buttonConnect;
TextView textPort;

static final int SocketServerPORT = 8080;

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

editTextAddress = (EditText) findViewById(R.id.address);
textPort = (TextView) findViewById(R.id.port);
textPort.setText("port: " + SocketServerPORT);
buttonConnect = (Button) findViewById(R.id.connect);

buttonConnect.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v) {
ClientRxThread clientRxThread =
new ClientRxThread(
editTextAddress.getText().toString(),
SocketServerPORT);

clientRxThread.start();
}});
}

private class ClientRxThread extends Thread {
String dstAddress;
int dstPort;

ClientRxThread(String address, int port) {
dstAddress = address;
dstPort = port;
}

@Override
public void run() {
Socket socket = null;

try {
socket = new Socket(dstAddress, dstPort);

File file = new File(
Environment.getExternalStorageDirectory(),
"test.txt");

byte[] bytes = new byte[1024];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(bytes, 0, bytes.length);
bos.write(bytes, 0, bytesRead);
bos.close();
socket.close();

MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
Toast.makeText(MainActivity.this,
"Finished",
Toast.LENGTH_LONG).show();
}});

} catch (IOException e) {

e.printStackTrace();

final String eMsg = "Something wrong: " + e.getMessage();
MainActivity.this.runOnUiThread(new Runnable() {

@Override
public void run() {
Toast.makeText(MainActivity.this,
eMsg,
Toast.LENGTH_LONG).show();
}});

} finally {
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

}

activity_main.xml
<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:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.androidsocketfiletransferclient.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" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="File Transfer Client"
android:textStyle="bold" />

<EditText
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="dstAddress" />

<TextView
android:id="@+id/port"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<Button
android:id="@+id/connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connect..." />

</LinearLayout>

Add permission of "android.permission.INTERNET" and "android.permission.WRITE_EXTERNAL_STORAGE" to AndroidManifest.xml.

download filesDownload the files.


Next:
Transfer image between Android devices, via Socket

More example of Android Network programming
- Bi-directional communication between Client and Server, using ServerSocket, Socket, DataInputStream and DataOutputStream