Transfer image between Android devices, via Socket

The post "File transfer via Socket, between Android devices" show how to send text file between Android devices using Socket. In this example, we are going to send image file of "png" via Socket, with ObjectOutputStream in server side and ObjectInputStream in client side.


The png file is fixed "android-er_sketch_1000.png" at ExternalStorageDirectory in server, and received file in client will be save as "test.png" at ExternalStorageDirectory.

android-er_sketch_1000.png
Here I list the MainActivity of both server and client. For the layout files, refer to the example of "File transfer via Socket, between Android devices".

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.ObjectOutputStream;
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;

/*
* Permission needed:
* <uses-permission android:name="android.permission.INTERNET"/>
* <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
*/

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(),
"android-er_sketch_1000.png");

byte[] bytes = new byte[(int) file.length()];
BufferedInputStream bis;
try {
bis = new BufferedInputStream(new FileInputStream(file));
bis.read(bytes, 0, bytes.length);

ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(bytes);
oos.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();
}
}

}
}
}

download filesDownload the files in Server side.


Client side MainActivity.java
package com.example.androidsocketfiletransferclient;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
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;

/*
* Permission needed:
* <uses-permission android:name="android.permission.INTERNET"/>
* <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
*/

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.png");

ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
byte[] bytes;
FileOutputStream fos = null;
try {
bytes = (byte[])ois.readObject();
fos = new FileOutputStream(file);
fos.write(bytes);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(fos!=null){
fos.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();
}
}
}
}
}

}

download filesDownload the files in client side.


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