I have a program that establishes a Bluetooth connection, reads the InputStream to a textView, and can disconnect from the module. While I can successfully disconnect and reconnect to the module (HC-05) as many times as I please, I can't get an InputStream read anymore after I reconnect. I believe it is because I don't know how to reinitialize the thread I'm using to read the InputStream. I am very new to java and android programming, any help with this issue would be appreciated.This is my code:
The textView for the read display is called 'Status' and I am hoping to "reset" the thread upon the onclick connect().
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
public class MainActivity extends AppCompatActivity implements Runnable {
private BluetoothAdapter adapter;
private InputStream inputStream;
private OutputStream outputStream;
private Thread thread;
private TextView Status;
private TextView Connection;
private BluetoothSocket socket = null;
private boolean threadStatusInitial=true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Status=(TextView) findViewById(R.id.StatusID);
Connection=(TextView) findViewById(R.id.ConnectionStatus);
adapter= BluetoothAdapter.getDefaultAdapter();
if(adapter==null){
Toast.makeText(this,"bluetooth is unavailable",Toast.LENGTH_SHORT).show();
finish();
return;
}
thread=new Thread(this);
}
public void connect(View view){
Set<BluetoothDevice> devices=adapter.getBondedDevices();
for(BluetoothDevice device:devices){
if(device.getName().startsWith("HC-05")){
try {
socket=device.createRfcommSocketToServiceRecord(device.getUuids()[0].getUuid());
socket.connect();
Connection.setText("Connected");
inputStream=socket.getInputStream();
outputStream=socket.getOutputStream();
if (threadStatusInitial){
thread.start();
threadStatusInitial=false; //this ensures that the thread.start() method will only be called during the first connection
}
} catch (IOException e) {
Toast.makeText(this,"Can't Connect",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
break;
}
}
}
public void Disconnect(View view) throws InterruptedException {
if (inputStream != null) {
try {inputStream.close();} catch (Exception e) {}
inputStream = null;
}
if (outputStream != null) {
try {outputStream.close();} catch (Exception e) {}
outputStream = null;
}
if (socket != null) {
try {socket.close();} catch (Exception e) {Toast.makeText(this,"Can't Connect",Toast.LENGTH_LONG).show();}
socket = null;
}
Connection.setText("Disconnected");
}
#Override
public void run() {
String textInput = "hi";
byte[] writeBytes=textInput.getBytes();
if(outputStream!=null){
try {
outputStream.write(writeBytes);
} catch (IOException e) {
Toast.makeText(this,"Unable to Write to Bluetooth ",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
while(inputStream!=null){
byte [] buffer=new byte[2048];
try {
int length=inputStream.read(buffer);
final String strReceived = new String(buffer, 0, length);
runOnUiThread(new Runnable(){
#Override
public void run() {
Status.setText(strReceived);
}});
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Related
I am attempting to create an android app that connects to an Bluetooth device and am struggling with connecting.When running the run() method when I try to connect it does not work and goes to the catch portion of the code giving me the output of "socket closed". i am not sure why the try is not working.
I am aware that my code has several flaws, i am on my 5th day of android developing, however any help I could get would be greatly appreciated. The big problem I need to fix is being able to connect to the device and ultimately being able to receive a stream of data from it.
public class BluetoothConnection extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
byte[] buffer;
BluetoothAdapter mmAdapter;
// Unique UUID for this application, you may use different
private static final UUID MY_UUID = UUID
.fromString("eb58f747-a241-4ccb-935d-04ac6039895d");
public BluetoothConnection(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmAdapter = null;
System.out.println("\n\n\n\n\n\n print is working? \n\n\n\n\n\n");
// Get a BluetoothSocket for a connection with the given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
e.printStackTrace();
}
mmSocket = tmp;
//now make the socket connection in separate thread to avoid FC
Thread connectionThread = new Thread(new Runnable() {
#Override
public void run() {
// Always cancel discovery because it will slow down a connection
Log.d("workkkkkk","$$$$$$$$$$$$$$$$****** printingggggg ******$$$$$$$$$$$$$$$$");
//mmAdapter.cancelDiscovery();
}
});
connectionThread.start();
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
System.out.println("\n\n\n\n\n\n socket connected\n\n\n\n\n\n");
} catch (IOException e) {
//connection to device failed so close the socket
try {
mmSocket.close();
System.out.println("\n\n\n\n\n\n socket closed\n\n\n\n\n\n");
} catch (IOException e2) {
System.out.println("\n\n\n\n\n\n in catch\n\n\n\n\n\n");
e2.printStackTrace();
}
}
tmpIn = mmSocket.getInputStream();
tmpOut = mmSocket.getOutputStream();
buffer = new byte[1024];
} catch (IOException e) {
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
// Keep listening to the InputStream while connected
while (true) {
try {
//read the data from socket stream
if(mmInStream != null) {
mmInStream.read(buffer);
}
// Send the obtained bytes to the UI Activity
} catch (IOException e) {
//an exception here marks connection loss
//send message to UI Activity
break;
}
}
}
public void write(byte[] buffer) {
try {
//write the data to socket stream
if(mmOutStream != null)
mmOutStream.write(buffer);
} catch (IOException e) {
e.printStackTrace();
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is being run in my DeviceList Class which is here. I am running into multiple problems here but the big one is pertaining to the BluetoothConnection.java however i am not sure if the issue is happening because of this class.
package com.example.curie.fairbanks_01;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothSocket;
import android.app.Activity;
import android.os.Bundle;
import java.io.IOException;
import android.util.Log;
import android.view.View;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.Switch;
import android.widget.Toast;
import android.content.Intent;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public class DeviceList extends Activity {
Button deviceSearch;
Switch btSwitch;
private BluetoothAdapter BA;
private Set<BluetoothDevice>pairedDevices;
private String instrumentName;
private UUID instrumentUUID;
BluetoothSocket socket;
BluetoothConnection connector;
ListView lv;
public static BluetoothDevice instrument;
PopupMenu pMenu;
ArrayList<MenuItem> popupList;
ArrayList<BluetoothDevice> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_list);
deviceSearch = (Button) findViewById(R.id.device_search);
deviceSearch.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
PopupMenu popup = new PopupMenu(DeviceList.this, findViewById(R.id.device_search));
pairedDevices = BA.getBondedDevices();
list = new ArrayList<BluetoothDevice>();
for (BluetoothDevice bt : pairedDevices) {
list.add(bt);
popup.getMenu().add(bt.getName());
popup.show();
}
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
ArrayList<BluetoothDevice> deviceArrayList = new ArrayList<BluetoothDevice>(pairedDevices);
Toast.makeText(DeviceList.this, "Testing: " + item.getTitle(), Toast.LENGTH_SHORT).show();
// instrument = deviceArrayList.get(deviceArrayList.indexOf(item.getItemId()));
instrument = deviceArrayList.get(0);
connector = new BluetoothConnection(instrument);
connector.run();
Toast.makeText(DeviceList.this, "Connected to : " + item.getTitle(), Toast.LENGTH_SHORT).show();
Intent myIntent = new Intent(DeviceList.this, InputActivity.class);
DeviceList.this.startActivity(myIntent);
return true;
}
});
}
});
btSwitch = (Switch) findViewById(R.id.switch1);
BA =BluetoothAdapter.getDefaultAdapter();
lv =(ListView) findViewById(R.id.listView);
if(BA.isEnabled())
btSwitch.setChecked(true);
else
btSwitch.setChecked(false);
// pMenu = new PopupMenu(this,findViewById(R.id.device_search));
}
public void list(View v){
// pairedDevices = BA.getBondedDevices();
//
// ArrayList list = new ArrayList();
//
// for(BluetoothDevice bt : pairedDevices){
//
// list.add(bt.getName());
// pMenu.getMenu().add(bt.toString());
// }
Toast.makeText(getApplicationContext(), "Showing Paired Devices",Toast.LENGTH_SHORT).show();
final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list);
lv.setAdapter(adapter);
}
public void onOff(View v)
{
if(BA.isEnabled())
{
BA.disable();
Toast.makeText(getApplicationContext(), " BT Turned off" ,Toast.LENGTH_LONG).show();
}
else
{ BA.enable();
Toast.makeText(getApplicationContext(), "BT Turned on" ,Toast.LENGTH_LONG).show();
}
}
public static BluetoothDevice getInstrument() {
return instrument;
}
}
this is what is running on the console when I select the device I would like to connect to:
I/System.out: $$$$$$$$$$$$$$$$****** in constructor ******$$$$$$$$$$$$$$$$
D/workkkkkk: $$$$$$$$$$$$$$$$****** printingggggg ******$$$$$$$$$$$$$$$$
D/BluetoothUtils: isSocketAllowedBySecurityPolicy start : device null
D/BluetoothSocket: connect(): myUserId = 0
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
I/System.out: $$$$$$$$$$$$$$$$****** socket closed ******$$$$$$$$$$$$$$$$
D/BluetoothSocket: getInputStream(): myUserId = 0
getOutputStream(): myUserId = 0
Why is it not connecting in the try?
I'm following this tutorial for creating an app with server-client chat. It is working like a charm in android emulators as described there. But I want to simulate it on my device. What about port forwarding in real devices?
I've tried connecting my two devices in a single hotspot and sending message. But it is not working. Do I need to change some code for that? or there is other method out there?
Any help will be appreciated!
I'm new to networking and android both.
Server code:
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
import android.os.Handler;
import android.widget.TextView;
public class MainActivity extends Activity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
public static final int SERVERPORT = 6000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text2);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
}
Client code:
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends Activity {
private Socket socket;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.0.2.2";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
I wrote the application in Android Studio which has to send 1 on Arduino Pro Mini. Data is sent but doesn't reach Arduino. I checked Arduino through Bluetooth Terminal and everything was OK so the problem is in code. What is wrong?
package com.example.niko.motoco;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
BluetoothAdapter btAdapter = null ;
BluetoothDevice btDevice = null;
BluetoothSocket btSocket = null;
final String LOG_TAG = "myLogs";
Button btConnect, btSend;
public TextView checkText;
private static final int REQUEST_ENABLE_BT = 1;
private static final int CONNECTEDdevice = 2;
Boolean connection = false;
private static String MAC = null;
UUID my_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
private ConnectedThread MyThread = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
checkText = (TextView) findViewById(R.id.checkText);
btConnect = (Button)findViewById(R.id.btConnect);
btSend = (Button)findViewById(R.id.btSend);
btAdapter = BluetoothAdapter.getDefaultAdapter();
if (btAdapter == null) {
Toast.makeText(getApplicationContext(),"Device does not support Bluetooth",Toast.LENGTH_LONG).show();
} else if (!btAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
btConnect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (connection) {
// disconnect
try {
btSocket.close();
connection = false;
btConnect.setText("Connect");
Toast.makeText(getApplicationContext(),"Bluetooht is disconnected:",Toast.LENGTH_LONG).show();
} catch (IOException error) {
Toast.makeText(getApplicationContext(),"Error;" + error,Toast.LENGTH_LONG).show();
}
} else {
// connect
Intent ListDevices = new Intent(MainActivity.this, ListDevices.class);
startActivityForResult(ListDevices,CONNECTEDdevice);
}
}
});
btSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
MyThread.write((byte) 1);
Toast.makeText(getApplicationContext(),"Sending 1",Toast.LENGTH_LONG).show();
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_ENABLE_BT:
if(resultCode == Activity.RESULT_OK) {
Toast.makeText(getApplicationContext(),"bluetooth is activated",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),"bluetooth is not activated",Toast.LENGTH_LONG).show();
finish();
}
break;
case CONNECTEDdevice :
if (resultCode == Activity.RESULT_OK) {
MAC = data.getExtras().getString(ListDevices.MACaddress);
btDevice = btAdapter.getRemoteDevice(MAC);
try {
btSocket = btDevice.createRfcommSocketToServiceRecord(my_UUID);
btSocket.connect();
connection = true;
btConnect.setText("Disconnect");
Toast.makeText(getApplicationContext(),"MAC of connected device:" + MAC,Toast.LENGTH_LONG).show();
MyThread = new ConnectedThread(btSocket);
//MyThread.start();
} catch (IOException error) {
connection = false;
Toast.makeText(getApplicationContext(),"Error:" + error,Toast.LENGTH_LONG).show();
}
}else {
Toast.makeText(getApplicationContext(),"didn't get MAC",Toast.LENGTH_LONG).show();
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket btSocket2;
private final OutputStream OutStream;
public ConnectedThread(BluetoothSocket socket) {
btSocket2 = socket;
OutputStream tmpOut = null;
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
OutStream = tmpOut;
}
public void write(byte bytes) {
try {
OutStream.write(bytes);
} catch (IOException e) { }
}
public void cancel() {
try {
btSocket2.close();
} catch (IOException e) { }
}
}
}
What's wrong ? At least those 2 pieces of code are wrong :
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
And later:
try {
OutStream.write(bytes);
} catch (IOException e) { }
When something goes wrong you catch the exception silently and loose all chances to identify the root cause.
Change the code to something like this :
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.(TAG, "Fail to get socket output stream" ,e);
}
And later :
try {
OutStream.write(bytes);
} catch (IOException e) {
Log.(TAG, "Fail to write on socket output stream" ,e);
}
Then re-run your code and look at the logcat. You will probably see the cause of your problems.
Trying to do android socket programming based on this tutorial
http://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/
I have my firewall turned off and anti virus disabled. If I make my server address to 127.0.0.1 I get the error in the title. If I make it my local IP address,it just sits at socket going to be created.I have tried it without and with port forwarding and setting it to the same port.
Client
package com.bennatpjose.androidsocketclient;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
private Socket socket;
private TextView text;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.52.7.179";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.textView1);
new Thread(new ClientThread()).start();
text.setText(text.getText().toString()+"Client Thread should be fired");
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
text.setText(text.getText().toString()+"\n"+"Click Event "+str);
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
text.setText(text.getText().toString()+"\n"+"Next is out.println("+str+")");
out.println(str);
text.setText(text.getText().toString()+"\n"+"out.println("+str+")");
} catch (UnknownHostException e) {
text.setText(text.getText().toString()+"\nPrint Writer UnknownHostException "+e.toString());
} catch (IOException e) {
text.setText(text.getText().toString()+"\nPrint Writer IOException "+e.toString());
} catch (Exception e) {
text.setText(text.getText().toString()+"\nPrint Writer Exception "+e.toString());
}
}
class ClientThread implements Runnable {
#Override
public void run() {
text.setText(text.getText().toString()+"\nInside client thread run method ");
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
//If I set address to my local ip it just sits here and doesn't show socket created.
text.setText(text.getText().toString()+"\n"+serverAddr +" Socket going to be Created");
socket = new Socket(serverAddr, SERVERPORT);
text.setText(text.getText().toString()+"\n"+socket.toString() +"Socket Created");
} catch (UnknownHostException e1) {
text.setText(text.getText().toString()+"\nClient Thread UnknownHostException "+e1.toString());
} catch (IOException e1) {
text.setText(text.getText().toString()+"\nClient Thread IOException "+e1.toString());
}catch (Exception e1) {
text.setText(text.getText().toString()+"\nClient Thread Exception "+e1.toString());
}
}
}
}
Server
package com.bennatpjose.androidsocketserver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
public class MainActivity extends Activity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
public static final int SERVERPORT = 6000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.text2);
text.setText(text.getText().toString()+"onCreate method started");
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
text.setText(text.getText().toString()+"\n"+"serverThread started");
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
text.setText("!!Socket Stopped!!");
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
text.setText(text.getText().toString()+socket+"\n");
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
}
So I figured it out. One of the mistakes I did was replacing the SERVER_IP with my local ip where as I should have left it at 10.0.2.2 since its a special loopback address android emulators.
10.0.2.2 Special alias to your host loopback interface (i.e., 127.0.0.1 on your development machine)
You also have to run the server first,set the port redirection and then run the client.
Look up Emulator networking section at http://developer.android.com/tools/devices/emulator.html
I am trying to write an app on android where, there is a multithreaded server running on a computer and in the app on the phone there is a button, once the user clicks that button a socket is opened between the server and the client. My problem is that once the user clicks that button I get a lot of runtime errors on my log cat. One of them is SocketException socket failed (Permission denied)
Here is the code for the activity that has the button that opens the socket with the server
package guc.edu.eg;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class Activity1 extends Activity {
Button start;
Button help;
Button credentials;
Socket socket;
//public DataInputStream in=null;
public PrintStream out=null;
InetAddress IP;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
//try {
//IP = InetAddress.getLocalHost();
//} catch (UnknownHostException e) {
// //TODO Auto-generated catch block
//e.printStackTrace();
//}
start = (Button) findViewById(R.id.start);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
socket= new Socket("127.0.0.1",4444);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//try {
//out = new PrintStream(socket.getOutputStream());
//out.println ("The socket is open at the phone!!");
//} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
//}
//try {
// in = new
//DataInputStream(socket.getInputStream());
// } catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
//}
Intent intent = new Intent(Activity1.this,Activity2.class);
startActivity(intent);
}
});
help = (Button) findViewById(R.id.help);
help.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Activity1.this,Activity3.class);
startActivity(intent);
finish();
}
});
credentials = (Button) findViewById(R.id.credentials);
credentials.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Activity1.this,Activity4.class);
startActivity(intent);
finish();
}
});
}
}
Here is the code for the Server class, that is actually placed in a different project other than the one that has the app code.
import java.io.*;
import java.net.*;
import java.util.LinkedList;
// Java extension packages
public class Server implements Runnable {
ServerSocket serverSocket;
Socket clientSocket;
int portNo;
LinkedList<ServerThread> allClients = new LinkedList<ServerThread>();
public Server(int port) {
portNo = port;
}
public void run() {
try {
serverSocket = new ServerSocket(portNo);
while (true) {
clientSocket = serverSocket.accept();
ServerThread x = new ServerThread(clientSocket, this);
allClients.add(x);
x.start();
}
} catch (EOFException eofException) {
System.out.println("Client terminated connection");
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
public void sendMessageToClient(String message) {
String[] x = message.split(",");
//for (int i = 0; i < allClients.size(); i++) {
//if (allClients.get(i).clientName.equals(x[2])) {
//allClients.get(i).sendMessage(x[1] + ": " + x[0]);
//return;
//}
//}
// if you didn't return then you couldn't reach your destination in your local server
// send the message to the network server to search for it
}
public String getLocalClientsNames() {
String names = "";
for (int i = 0; i < allClients.size(); i++) {
names += allClients.get(i).clientName + ",";
}
return names;
}
public void sendClientNamesToAll() {
//net.sendAllClientNames();
}
public static void main(String [] args) {
Server server = new Server(4444);
new Thread(server).start();
}
}
Here is the ServerThread class placed at the same package with the Server class
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class ServerThread extends Thread {
private Socket clientSocket;
private Server server;
String clientName;
private ObjectOutputStream output;
private ObjectInputStream input;
public ServerThread(Socket client, Server s) {
this.clientSocket = client;
this.server = s;
}
#Override
public void run() {
try {
output = new ObjectOutputStream(clientSocket.getOutputStream());
output.flush();
input = new ObjectInputStream(clientSocket.getInputStream());
processConnection();
closeConnection();
} catch (IOException e) {
System.out.println("in or out failed");
}
}
private void processConnection() throws IOException {
String message = "!!";
System.out.println("mada5alsh el while");
while (!message.equalsIgnoreCase("Client>> end")) {
try {
System.out.println("da5al el while");
message = (String) input.readObject();
System.out.print(message);
if (message.equalsIgnoreCase("Name")) {
clientName = (String) input.readObject();
server.sendClientNamesToAll();
} else {
server.sendMessageToClient(message);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public void closeConnection() throws IOException {
output.close();
input.close();
clientSocket.close();
}
public void sendMessage(String message) {
try {
output.writeObject(message);
output.flush();
} catch (IOException ioException) {
//do
}
}
}
I think it might be something that has to do with the manifest file so I added this line of code to it
`<uses-permission android:name="android.permission.INTERNET"></uses-permission>`
You create your client socket in the main thread which is not permitted.
Use a separate thread or use AsyncTask.
Adding <uses-permission android:name="android.permission.INTERNET"></uses-permission> to you AndroidManifest.xml should do the trick.