I am connecting two devices using p2p wifi direct. I have successfully sent a text message from one device to another but when it comes to sending an image I'm stuck. I tried to encode the image and decode on another side but right now the image is being sent successfully, however on the receiving end it doesn't show any image but the specific folder is being created, but when I open the image through the File Manager, it says "File format not supported" and the image doesn't open. The image has a size of 2.92KB.
One more thing I want to ask is how can I send to specific device, I've tried to put the receiving device's Inet address but it doesn't work for me.
Here is my code
For server side
public class ServerClass extends Thread {
Socket socket;
ServerSocket serverSocket;
#Override
public void run() {
try {
serverSocket = new ServerSocket(8888);
socket = serverSocket.accept();
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class SendReceive extends Thread {
private Socket socket;
private InputStream inputStream;
private OutputStream outputStream;
private DataInputStream dataInputStream;
int length;
byte[] Bbytes;
public SendReceive(Socket sckt) {
socket = sckt;
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
int bytes;
while (socket != null) {
try {
dataInputStream=new DataInputStream(inputStream);
length=dataInputStream.readInt();
Bbytes=new byte[length];
dataInputStream.readFully(Bbytes,0,Bbytes.length);
bytes = inputStream.read(Bbytes);
handler.obtainMessage(MESSAGE_READ, bytes, -1,
Bbytes).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//sending images
public void writeImageData(byte[] bytes){
try {
DataOutputStream dataOutputStream=new
DataOutputStream(outputStream);
dataOutputStream.writeInt(bytes.length);
dataOutputStream.write(bytes, 0, bytes.length);
}catch (IOException e) {
e.printStackTrace();
}
}
}
The client side
public class ClientClass extends Thread {
Socket socket;
String hostAdd;
public ClientClass(InetAddress hostAddress) {
hostAdd = hostAddress.getHostAddress();
socket = new Socket();
}
#Override
public void run() {
try {
socket.connect(new InetSocketAddress(hostAdd, 8888), 700);
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
To send image to client and I am getting this toast as successful
public class SendImageClient extends AsyncTask<byte[], Void, Void> {
#Override
protected Void doInBackground(byte[]... voids) {
try {
sendReceive.writeImageData(voids[0]);
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "Image sent",
Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
The handler for receive message and reading it
Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(#NonNull Message msg) {
switch (msg.what) {
case MESSAGE_READ:
byte[] readBuff = (byte[]) msg.obj;
Bitmap bitmap=
BitmapFactory.decodeByteArray(readBuff,0,readBuff.length);
imageView22.setImageBitmap(bitmap);
saveImage(bitmap);
break;
}
return true;
}
});
//to save image in device
private void saveImage(Bitmap finalBitmap){
String root= Environment.getExternalStorageDirectory().toString();
File myDir= new File(root+"/saved_images");
myDir.mkdirs();
Random generator= new Random();
int n=10000;
n=generator.nextInt(n);
String fname="Image-"+n+".jpg";
File file=new File(myDir,fname);
if(file.exists()){
file.delete();
}
try {
FileOutputStream out=new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100,out);
out.flush();
out.close();
Toast.makeText(this, "image saved ", Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Lastly the send button
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
drawable = (BitmapDrawable) imageView.getDrawable();
bitmap = drawable.getBitmap();
imageView.setImageBitmap(bitmap);
ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 0, byteArrayOutputStream);
byte[] array = byteArrayOutputStream.toByteArray();
SendImageClient sendImageClient = new SendImageClient();
sendImageClient.execute(array);
}
});
I'd appreciate any suggestions. Thank you in advance.
Related
I've been working on a project where i would send a file from the android app i wrote to my esp8266; the esp8266 then will write the file onto the SD card. but when esp receives the file for example a .jpg, it's all garbled and noisy.
and if i receive a .txt file it will always add a (¬í ur [B¬óøTà xp ¬) at the beginning, regardless of what method i use.
Here's my android code:
(Server thread)
Socket mySocket = null;
ServerSocket serverSocket = null;
class ServerThread implements Runnable{
int serverPort;
public ServerThread(int serverPort){
this.serverPort = serverPort;
}
#Override
public void run() {
try {
serverSocket = new ServerSocket(serverPort);
mySocket = serverSocket.accept();
output = new PrintWriter(mySocket.getOutputStream());
input = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
Log.i("connection", "server");
runOnUiThread(new Runnable() {
#Override
public void run() {
connection_state = true;
LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
TextView thisText = new TextView(MainActivity.this);
thisText.setId(append);
thisText.setText("Server port: " + 8080 + " ... A client just made connection");
thisText.setTextSize(20);
thisText.setBackgroundColor(Color.rgb(25, 24, 24));
thisText.setTextColor(Color.rgb(0, 100, 0));
append++;
thisText.setGravity(20);
thisText.setLayoutParams(textParams);
myTexts.addView(thisText);
}
});
new Thread(new ReceiveStringThread()).start();
} catch (IOException e) {
e.printStackTrace();
Log.i("connection", "couldn't establish connection");
} finally {
try {
if (socket != null)
socket.close();
if (serverSocket != null)
serverSocket.close();
}catch (IOException e){
e.getStackTrace();
}
}
}
}
Send file thread:
class SendFileThread implements Runnable{
String filePath;
SendFileThread(String filePath) {
this.filePath = filePath;
}
#Override
public void run() {
if(connection_state) {
File findFile = new File(filePath);
byte[] sendIt = new byte[(int) findFile.length()];
try {
BufferedInputStream bufferFile = new BufferedInputStream(new FileInputStream(findFile));
bufferFile.read(sendIt, 0, sendIt.length);
ObjectOutputStream oos = new ObjectOutputStream(mySocket.getOutputStream());
oos.writeObject(sendIt);
oos.flush();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "File was sent successfully. size: " +
(int) findFile.length() + " bytes", Toast.LENGTH_SHORT).show();
}
});
} catch (IOException e) {
e.getStackTrace();
}finally {
try {
mySocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
and here's my arduino code for esp8266:
#include <ESP8266WiFi.h>
#include <SD.h>
#ifndef STASSID
#define STASSID "ESP_CLIENT"
#define STAPSK "client-1234"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const char* host = "192.168.1.103";
const uint16_t port = 8080;
boolean connectionStatus = false;
byte buffer_array[10] = {'0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00'};
int num_read;
WiFiClient client;
void setup() {
Serial.begin(57600);
//.................Initiate SD card................//
if(!SD.begin(SS)){
Serial.println("SD card initialization failed!");
return;
}else{
Serial.println("SD card initialized successfully");
}
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
char *printBytes(byte *bytes) {
char bytesStr[10];
sprintf(bytesStr, "%02X", *bytes);
Serial.print("byte: ");
Serial.println(bytesStr);
return bytesStr;
}
void loop() {
if(!connectionStatus){
Serial.print("connecting to ");
Serial.print(host);
Serial.print(':');
Serial.println(port);
if (!client.connect(host, port)) {
Serial.println("********************************************Connection failed************************************************");
connectionStatus = false;
delay(1000);
return;
}else{
Serial.println("********************************************Connection established with server***********************************************");
connectionStatus = true;
}
Serial.println("sending data to server");
if (client.connected()) {
client.println("hello from ESP8266");
}
}
if(client.available()){
Serial.println("Receiving...");
num_read = client.readBytesUntil('\n',buffer_array, 10);
Serial.println("bytes read: " + (String)num_read);
printBytes(buffer_array);
File appendSD = SD.open("/testESP32.txt", FILE_WRITE);
if(!appendSD){
Serial.println("not found");
return;
}else{
Serial.println("Writing byte to file...");
appendSD.write(buffer_array, num_read);
appendSD.close();
}
}
}
and regardless of which mode i put them into, whether it'll be esp as server and android device as client or reverse, it won't make a difference at all.
anyone knows how to fix this?
i modified the SendFileThread as below but it only worked for sending .txt files correctly. but sending image files like .jpg problem still stands.
class SendFileThread implements Runnable{
String filePath;
SendFileThread(String filePath) {
this.filePath = filePath;
}
#Override
public void run() {
if(connection_state) {
File findFile = new File(filePath);
byte[] sendIt = new byte[(int) findFile.length()];
try {
BufferedInputStream bufferFile = new BufferedInputStream(new FileInputStream(findFile));
bufferFile.read(sendIt, 0, sendIt.length);
OutputStream os= mySocket.getOutputStream();
os.write(sendIt);
os.flush();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "File was sent successfully. size: " +
(int) findFile.length() + " bytes", Toast.LENGTH_SHORT).show();
}
});
} catch (IOException e) {
e.getStackTrace();
}finally {
try {
mySocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}else{
}
}
}
and i wanna be able to send all kinds of data like .pdf .doxs as well and ObjectOutputStream sends all this kinds of files just fine if although i'm sending them to another android phone not esp8266
SOLVED: i used
client.read(buffer_array, 10);
for image files instead of
client.readBytesUntil('\n', buffer_array, 10);
and in android changed
ObjectOutputStream oos = new ObjectOutputStream(mySocket.getOutputStream());
oos.writeObject(sendIt);
to
OutputStream os= mySocket.getOutputStream();
os.write(sendIt);
and it finally worked for all types of files!
I am making server-client program, the server is Java on the computer and the client is android app (android studio) and I try to send image from the server to the client, and to show this image on the client's screen by ImageView. The problem is that sometimes its work and sometimes it doesn't work. Looks like there are times that ByteArrayOutputStream.size() return negative value in the client side in the variable len (that keep the length). When the return value is positive it works. Why am I getting negative values (sometimes)?
Server code:
public class Server extends JFrame {
BufferedImage bi,inputImage;
JButton btn;
ServerSocket serverSocket;
Socket socket;
private Scanner in;
private PrintWriter out;
public Server(){
File imageFile = new File("ssss.PNG");
try {
bi = ImageIO.read(imageFile);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
this.add(btn = new JButton("Send"), BorderLayout.NORTH);
this.add(new JLabel(new ImageIcon(bi)), BorderLayout.CENTER);
this.setSize(200, 180);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
try{
serverSocket = new ServerSocket(8000);
socket = serverSocket.accept();
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream(), true);
}
catch(IOException ex){
System.err.println(ex);
}
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
out.println("IMAGE");
sendImage(new File("ssss.PNG"));
// try {
// ImageIO.write(bi, "PNG", socket.getOutputStream());
//} catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
// }
}
});
}
public static void main(String[] args) {
new Server();
}
public void sendImage(File file){
try {
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
DataInputStream dis = new DataInputStream(new FileInputStream(file));
ByteArrayOutputStream ao = new ByteArrayOutputStream();
int read = 0;
byte[] buf = new byte[dis.available()];
while ((read = dis.read(buf)) > -1) {
ao.write(buf, 0, read);
}
System.out.println("ao.size(): "+ao.size());
out.writeInt(ao.size());
out.write(ao.toByteArray());
out.flush();
// out.close();
// dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client code(android):
public class MainActivity extends AppCompatActivity {
public Socket socket;
public PrintWriter out;
public Scanner in;
public TextView textView;
public DataOutputStream dos=null;
public DataInputStream dis=null;
public ImageView imageView;
public Bitmap bitmap;
private static final int SERVERPORT = 8000;
private static final String SERVER_IP = "192.168.5.59";
public static final String TAG="TAG";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.text);
imageView=(ImageView)findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.ic_launcher_background);
new Thread(new ClientThread()).start();
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
Log.d(TAG, "try to connect...");
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream(), true);
Log.d(TAG, "connected1234");
while (in.hasNextLine()) {
String response = in.nextLine();
if (response.startsWith("IMAGE")) {
InputStream in = socket.getInputStream();
Log.d(TAG, "in: "+in);
DataInputStream input = new DataInputStream(in);
Log.d(TAG, "input: "+input);
byte[] data;
int len= input.readInt();
Log.d(TAG, "len: "+len);
data = new byte[len];
Log.d(TAG, "data: "+data);
if (len > 0) {
input.readFully(data,0,data.length);
}
final Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data .length);
Log.d(TAG, "Bitmap: "+bitmap);
runOnUiThread(new Runnable() {
#Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
The error:
len: -298696669
E/AndroidRuntime: FATAL EXCEPTION: Thread-5
Process: com.example.sendimageexample, PID: 17224
java.lang.NegativeArraySizeException: -298696669
at com.example.sendimageexample.MainActivity$ClientThread.run(MainActivity.java:80)
at java.lang.Thread.run(Thread.java:784)`
I solved it!
client code:
public class MainActivity extends AppCompatActivity {
public Socket socket;
public ImageView imageView;
private static final int SERVERPORT = 8000;
private static final String SERVER_IP = "192.168.5.59";
public static final String TAG="TAG";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView=(ImageView)findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.ic_launcher_background);
new Thread(new ClientThread()).start();
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
Log.d(TAG, "try to connect...");
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Log.d(TAG, "Adder: "+serverAddr);
socket = new Socket(serverAddr, SERVERPORT);
InputStream in = socket.getInputStream();
Log.d(TAG, "in: "+in);
DataInputStream input = new DataInputStream(in);
Log.d(TAG, "input: "+input);
Log.d(TAG, "connected1234");
byte[] data;
int len= input.readInt();//-298696669//17976
Log.d(TAG, "len: "+len);
data = new byte[len];
Log.d(TAG, "data: "+data);
if (len > 0) {
input.readFully(data,0,data.length);
}
final Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data
.length);
Log.d(TAG, "Bitmap: "+bitmap);
runOnUiThread(new Runnable() {
#Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
ByteArrayOutputStream bos =new ByteArrayOutputStream();
Bitmap bitmap1=BitmapFactory.decodeResource(getResources(),R.drawable.image22);
Log.d(TAG, "bitmap1: "+bitmap1);
bitmap1.compress(Bitmap.CompressFormat.PNG,0,bos);
byte []array=bos.toByteArray();
OutputStream outputStream=socket.getOutputStream();
DataOutputStream dos=new DataOutputStream(outputStream);
dos.writeInt(bos.size());
dos.write(array,0,array.length);
Log.d(TAG, "bos.size: "+bos.size());
Log.d(TAG, "bos.array: "+bos.toByteArray());
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
server code:
public class Server extends JFrame {
BufferedImage bi,inputImage;
JButton btn;
ServerSocket serverSocket;
Socket socket;
private Scanner in;
private PrintWriter out;
Server jframe=this;
public Server(){
File imageFile = new File("ssss.PNG");
try {
bi = ImageIO.read(imageFile);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
this.add(btn = new JButton("Send"), BorderLayout.NORTH);
//this.add(new JLabel(new ImageIcon(bi)), BorderLayout.CENTER);
this.setSize(200, 180);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
try{
serverSocket = new ServerSocket(8000);
socket = serverSocket.accept();
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream(), true);
}
catch(IOException ex){
System.err.println(ex);
}
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
sendImage(new File("ssss.PNG"));
InputStream inputStream;
try {
inputStream = socket.getInputStream();
DataInputStream dis=new DataInputStream(inputStream);
int size = dis.readInt();
System.out.println("size: "+size);
byte[] imageAr = new byte[size];
dis.readFully(imageAr);
System.out.println("imageAr: "+imageAr);
System.out.println("dis: "+dis);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageAr));
jframe.add(new JLabel(new ImageIcon(image)), BorderLayout.CENTER);
revalidate();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// try {
// ImageIO.write(bi, "PNG", socket.getOutputStream());
//} catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
// }
}
});
}
public static void main(String[] args) {
new Server();
}
public void sendImage(File file){
try {
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
DataInputStream dis = new DataInputStream(new FileInputStream(file));
ByteArrayOutputStream ao = new ByteArrayOutputStream();
int read = 0;
byte[] buf = new byte[dis.available()];
while ((read = dis.read(buf)) > -1) {
ao.write(buf, 0, read);
System.out.println("read: "+read);
System.out.println("buf: "+buf);
}
System.out.println("ao.size(): "+ao.size());
out.writeInt(ao.size());
System.out.println("ao.toByteArray(): "+ao.toByteArray());
out.write(ao.toByteArray());
out.flush();
// out.close();
// dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I am implementing a socket application where one phone will be a client and the other will be a server. The program is able to send strings using print writer just fine from the client to the sever but when i try to send an image file, it throws an exception. I'd really appreciate if someone could help me out.
Here is the code for the server
public class ServerActivity extends Activity {
private TextView serverStatus;
private ImageView profile;
// DEFAULT IP
public static String SERVERIP = "10.0.2.15";
// DESIGNATE A PORT
public static final int SERVERPORT = 8080;
private Handler handler = new Handler();
private ServerSocket serverSocket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.server);
serverStatus = (TextView) findViewById(R.id.server_status);
profile = (ImageView) findViewById(R.id.image);
String filepath = "/sdcard/DCIM/time table.png";
File imagefile = new File(filepath);
FileInputStream fis = null;
try {
fis = new FileInputStream(imagefile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
profile.setImageBitmap(bm);
SERVERIP = getLocalIpAddress();
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
//String line;
byte [] line;
Bitmap bitmap;
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// LISTEN FOR INCOMING CLIENTS
Socket client = serverSocket.accept();
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Connected.");
}
});
try {
/*InputStream in = client.getInputStream();
line = null;
in.read(line);
Log.d("ServerActivity", line.toString());
bitmap = BitmapFactory.decodeByteArray(line , 0, line.length);*/
int bytesRead;
int current = 0;
int filesize=65383;
byte [] mybytearray2 = new byte [filesize];
InputStream is = client.getInputStream();
FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/IMG-20130112-WA0011.jpeg"); // destination path and name of file
//FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray2,0,mybytearray2.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray2, current, (mybytearray2.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray2, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
//System.out.println(end-start);
bos.close();
handler.post(new Runnable() {
#Override
public void run() {
profile.setImageBitmap(bitmap);
//serverStatus.setText(line);
}
});
/*BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
line = null;
while ((line = in.readLine()) != null) {
Log.d("ServerActivity", line);
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText(line);
// DO WHATEVER YOU WANT TO THE FRONT END
// THIS IS WHERE YOU CAN BE CREATIVE
}
});
}*/
break;
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
// GETS THE IP ADDRESS OF YOUR PHONE'S NETWORK
private String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); }
}
}
} catch (SocketException ex) {
Log.e("ServerActivity", ex.toString());
}
return null;
}
#Override
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And this is the client side code
public class ClientActivity extends Activity {
private EditText serverIp;
private Button connectPhones;
private String serverIpAddress = "";
private boolean connected = false;
private Handler handler = new Handler();
private Socket socket;
private ImageView profile;
private byte [] imgbyte;
String filepath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.client);
serverIp = (EditText) findViewById(R.id.server_ip);
connectPhones = (Button) findViewById(R.id.connect_phones);
connectPhones.setOnClickListener(connectListener);
profile = (ImageView) findViewById(R.id.imageView1);
filepath = "/sdcard/small.jpg";
File imagefile = new File(filepath);
FileInputStream fis = null;
try {
fis = new FileInputStream(imagefile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
imgbyte = getBytesFromBitmap(bm);
profile.setImageBitmap(bm);
}
private OnClickListener connectListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (!connected) {
serverIpAddress = serverIp.getText().toString();
if (!serverIpAddress.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
};
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
socket = new Socket(serverAddr, ServerActivity.SERVERPORT);
connected = true;
while (connected) {
try {
/*File myFile = new File (filepath);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = socket.getOutputStream();
Log.d("ClientActivity", "C: Sending command.");
//System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();*/
Log.d("ClientActivity", "C: Sending command.");
/*PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);*/
// WHERE YOU ISSUE THE COMMANDS
OutputStream output = socket.getOutputStream();
Log.d("ClientActivity", "C: image writing.");
output.write(imgbyte);
output.flush();
// out.println("Hey Server!");
Log.d("ClientActivity", "C: Sent.");
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
connected = false;
}
}
}
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
socket.close();
connected = false;
} catch (IOException e) {
e.printStackTrace();
}
}
public byte[] getBytesFromBitmap(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 70, stream);
return stream.toByteArray();
}
}
update:
The exception is thrown at the server side code. Its the exception which reads :"Oops. Connection interrupted. Please reconnect your phones."
This is the exception that is thrown:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Thanks everyone , I found the error.
The toast messages have to be inside the UI thread or the handler . As I had a few of them in a non UI thread, it began to throw the exception.
I am implementing a socket application where one phone will be a client and the other will be a server. The program is able to send strings using print writer just fine from the client to the sever but when i try to send an image file, it throws an exception. I'd really appreciate if someone could help me out.
Here is the code for the server
public class ServerActivity extends Activity {
private TextView serverStatus;
private ImageView profile;
// DEFAULT IP
public static String SERVERIP = "10.0.2.15";
// DESIGNATE A PORT
public static final int SERVERPORT = 8080;
private Handler handler = new Handler();
private ServerSocket serverSocket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.server);
serverStatus = (TextView) findViewById(R.id.server_status);
profile = (ImageView) findViewById(R.id.image);
String filepath = "/sdcard/DCIM/time table.png";
File imagefile = new File(filepath);
FileInputStream fis = null;
try {
fis = new FileInputStream(imagefile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
profile.setImageBitmap(bm);
SERVERIP = getLocalIpAddress();
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
//String line;
byte [] line;
Bitmap bitmap;
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// LISTEN FOR INCOMING CLIENTS
Socket client = serverSocket.accept();
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Connected.");
}
});
try {
/*InputStream in = client.getInputStream();
line = null;
in.read(line);
Log.d("ServerActivity", line.toString());
bitmap = BitmapFactory.decodeByteArray(line , 0, line.length);*/
int bytesRead;
int current = 0;
int filesize=65383;
byte [] mybytearray2 = new byte [filesize];
InputStream is = client.getInputStream();
FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/IMG-20130112-WA0011.jpeg"); // destination path and name of file
//FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray2,0,mybytearray2.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray2, current, (mybytearray2.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray2, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
//System.out.println(end-start);
bos.close();
handler.post(new Runnable() {
#Override
public void run() {
profile.setImageBitmap(bitmap);
//serverStatus.setText(line);
}
});
/*BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
line = null;
while ((line = in.readLine()) != null) {
Log.d("ServerActivity", line);
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText(line);
// DO WHATEVER YOU WANT TO THE FRONT END
// THIS IS WHERE YOU CAN BE CREATIVE
}
});
}*/
break;
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
// GETS THE IP ADDRESS OF YOUR PHONE'S NETWORK
private String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); }
}
}
} catch (SocketException ex) {
Log.e("ServerActivity", ex.toString());
}
return null;
}
#Override
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And this is the client side code
public class ClientActivity extends Activity {
private EditText serverIp;
private Button connectPhones;
private String serverIpAddress = "";
private boolean connected = false;
private Handler handler = new Handler();
private Socket socket;
private ImageView profile;
private byte [] imgbyte;
String filepath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.client);
serverIp = (EditText) findViewById(R.id.server_ip);
connectPhones = (Button) findViewById(R.id.connect_phones);
connectPhones.setOnClickListener(connectListener);
profile = (ImageView) findViewById(R.id.imageView1);
filepath = "/sdcard/small.jpg";
File imagefile = new File(filepath);
FileInputStream fis = null;
try {
fis = new FileInputStream(imagefile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
imgbyte = getBytesFromBitmap(bm);
profile.setImageBitmap(bm);
}
private OnClickListener connectListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (!connected) {
serverIpAddress = serverIp.getText().toString();
if (!serverIpAddress.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
};
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
socket = new Socket(serverAddr, ServerActivity.SERVERPORT);
connected = true;
while (connected) {
try {
/*File myFile = new File (filepath);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = socket.getOutputStream();
Log.d("ClientActivity", "C: Sending command.");
//System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();*/
Log.d("ClientActivity", "C: Sending command.");
/*PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);*/
// WHERE YOU ISSUE THE COMMANDS
OutputStream output = socket.getOutputStream();
Log.d("ClientActivity", "C: image writing.");
output.write(imgbyte);
output.flush();
// out.println("Hey Server!");
Log.d("ClientActivity", "C: Sent.");
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
connected = false;
}
}
}
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
socket.close();
connected = false;
} catch (IOException e) {
e.printStackTrace();
}
}
public byte[] getBytesFromBitmap(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 70, stream);
return stream.toByteArray();
}
}
update:
The exception is thrown at the server side code. Its the exception which reads :"Oops. Connection interrupted. Please reconnect your phones."
This is the exception that is thrown:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Thanks everyone , I found the error.
The toast messages have to be inside the UI thread or the handler . As I had a few of them in a non UI thread, it began to throw the exception.
I have a simple connection activity:
package com.example.conn08;
import ...;
public class MainActivity extends Activity
{
public static Socket clientSocket;
public static DataOutputStream outToServer;
public static PrintWriter outTest;
public static BufferedReader inToServer;
With PrintWriter outTest I test server's availability:
If the user has no Internet, or the server doesn't work, I put Thread on a pause with Boolean shouldContinue.
private Thread mThread;
private final Object lock = new Object();
private Boolean shouldContinue = true;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mThread = new Thread(new Runnable()
{
public void run()
{
while (true)
{
synchronized(lock)
{
try
{
lock.wait(); // lock the Thread
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
while (shouldContinue)
{
try
{
final String data = inToServer.readLine();
if (data != null)
{
Log.v("data", data);
runOnUiThread(new Runnable()
{
#Override
public void run()
{
String put[] = data.split("#");
//Data parsing
}
});
}
}
catch (IOException e)
{
e.printStackTrace();
}
Check on availability of the server:
try {
if(clientSocket.getInputStream().read() == -1)
{
Log.v("Connection: ", "lost");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
mThread.start();
Connect();
}
public void Connect()
{
shouldContinue = true;
try
{
clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress("localhost", 15780), 30000);
outToServer = new DataOutputStream(clientSocket.getOutputStream());
inToServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
outTest = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(clientSocket.getOutputStream())), true);
synchronized(lock)
{
lock.notify();
}
sendUTF("3#kokoko"); //send the message!
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void sendUTF(String str)
{
try
{
byte[] buf = str.getBytes("UTF-8");
outToServer.write(buf, 0, buf.length);
outToServer.writeBytes("\n");
outToServer.flush();
}
catch (IOException e)
{
e.printStackTrace();
outServ.setText("Нет соединения!");
}
}
}
Problem in that when I don't use the
if(clientSocket.getInputStream().read() == -1)
And send data to server like here:
sendUTF("3#kokoko");
All is fine, but if I use it, on server I see this message like
"#kokoko" - I lose the first character of the message and my socket is crushed! Help me please