I do only have this problem with an outgoing connection. I coppied most parts of my sourcecode from the example http://developer.android.com/guide/topics/wireless/bluetooth.html
Therefore I don´t really know whats the cause of this problem is...
First of all the code where the IOException occures:
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);
break;
}
Every time I connect my phone to my tablet accept() throws an IOException on my phone:
BluetoothChatService Socket Type: nullaccept() failed
BluetoothChatService java.io.IOException: Operation Canceled
I believe this is somehow related to the problem that is described in this blog:
http://www.androiddiscuss.com/1-android-discuss/86844.html
By the way the BluetoothConnection works well, but my phone can´t receive any data.
Edit: I have just realized that a bluetooth connection from my Galaxy S to my Motorola Xoom could not be established with other popular bluetooth apps from the market...
If I connect the other way round, from my tablet to my phone, the tablet just reboots completely.
It could be an authentication issue. Are your devices paired?
Related
Problem
How can I differentiate between being unable to establish a Bluetooth connection with a remote Android device because:
scenario 1: the remote device is out of range, or its Bluetooth is disabled.
scenario 2: the remote device is in range, but there is no server socket on the remote device to accept my connection.
What I've tried
I could not differentiate between exceptions thrown when connecting because it threw the identical exceptions in both cases:
java.io.IOException: read failed, socket might closed or timeout, read ret -1
I could not use fetchUuidsWithSdp() to check if my UUID supported by the remote device because it behaves the same way in either scenario...according to the documentation:
This API is asynchronous and {#link #ACTION_UUID} intent is sent, with the UUIDs supported by the remote end. If there is an error in getting the SDP records or if the process takes a long time, {#link #ACTION_UUID} intent is sent with the UUIDs that is currently present in the cache...
it's behaviour also seems sort of unpredictable according to this SO thread.
lastly, I didn't want to use sdpSearch to differentiate between the two, because that was added in API 23, and I want to be able to support down to API 19.
You can determine if a device is in range by trying to connect to a standard UUID that is usually available on Android devices. If the call to connect:
fails, then remote device is out of range or its Bluetooth is disabled.
succeeds, then the remote device is in range and you should close the connection and then try to connect to your app's UUID...if that fails, then there was no listening socket...if it succeeds, then all is well.
Example code:
public BluetoothSocket connect(BluetoothDevice remoteDevice) throws IOException
{
OPP_UUID = UUID.fromString("00001105-0000-1000-8000-00805f9b34fb");
// check if remote device is in range...throw exception if out of range
try
{
BluetoothSocket socket = remoteDevice
.createRfcommSocketToServiceRecord(OPP_UUID);
socket.connect();
socket.close();
}
catch(IOException ex)
{
throw new IOException("out of range",ex);
}
// try to connect to service on remote device...throw exception if UUID
// is not available
try
{
BluetoothSocket socket = remoteDevice
.createRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
return socket;
}
catch(IOException ex)
{
throw new IOException("no listening server socket",ex);
}
}
I used BluetoothDevice.getUuids() to get the UUIDs available on one of my Android devices. It gave me this list:
0000110a-0000-1000-8000-00805f9b34fb - Advanced Audio Distribution Profile (0x110a)
00001105-0000-1000-8000-00805f9b34fb - Object Push Profile (0x1105) // least invasive one...it seems
00001115-0000-1000-8000-00805f9b34fb - Personal Area Networking Profile (0x1115)
0000112f-0000-1000-8000-00805f9b34fb - Phonebook Access (0x112f) // this works!
00001112-0000-1000-8000-00805f9b34fb - Headset - Audio Gateway (0x1112)
0000111f-0000-1000-8000-00805f9b34fb - Handsfree Audio Gateway (0x111f)
00001132-0000-1000-8000-00805f9b34fb - Message Access Profile (0x1132) // this works too!
00000000-0000-1000-8000-00805f9b34fb - Base UUID (0x0000) // couldn't get this to work :(
Standard UUIDs from Bluetooth spec.
I'm writing an Android app to communicate with a Windows service over socket connections.
The code is working but I want to add the ability to detect devices connected on local network so the app can determine which computer is running the windows service I want, I'm using the code below which I got from this website too. My issue is the code below only detects android devices and doesn't detect my laptop. I can ping my device from my laptop and ping my laptop from my device, so what to do from here?
public void checkHosts(String subnet) {
int timeout = 1000;
for (int i = 1; i < 254; i++) {
String host = subnet + "." + i;
try {
if (InetAddress.getByName(host).isReachable(timeout)) {
System.out.println(host + " is reachable");
System.out.println("Host Name: "
+ InetAddress.getByName(host).getHostName());
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
InetAddress.isReachable() is not very reliable.
If ICMP messages are blocked you won't get an answer.
What you could do is sending a broadcast message.
Your server application has to listen for this message and answer it.
This way you get the server IP address and you can connect to it.
And you have to send only one message to reach all hosts in the subnet.
Example code for sending and receiving broadcast messages
Thank you everyone I ended up creating a socket connection to each IP in the network and displaying host name from the socket. it showed me all devices whether they are android devices or windows machines.
Of course since I made the socket listen at port 8000 on both device and computer, so using a socket will give result IF AND ONLY IF both ends are listening on the same port, and I only care about computers that are running my service.
I really appreciate all the suggestions and help :)
Working on a client-server android application. The clients are polling the bufferedinputstream (in) for server messages, meanwhile also repeatedly checking if server is reachable so they can terminate instantly when server goes offline.
try {
while (true) {
if (MainActivity.in.available() > 0) {
message = MainActivity.readInput();
break;
}
Thread.sleep(100);
}
} catch (IOException e) {Log.e("myoutput", e.toString()); serverOffline = true; } //server probably offline?
catch (InterruptedException e2) {}
On one of my test devices (android 2.2) this works as I thought, as soon as I close down the server the IOException is triggered. Although on my second test device (android 4.3) the IOException is not triggered (compling with API 8). But I'm starting to think this is not a device thing as I tried running both API 8 and 18 in the emulator and it didn't trigger.
Any ideas?
I'm probably not providing all essential information to get any help from here, please let me know if so and I'll provide!
I am working on a bluetooth application which involves connection of my android bluetooth application with a server running on computer. The server is also a bluetooth application made using blue-cove api.
The problem i am facing now that i am unable to make connection between my mobile app and that computer server application.
here is my code for android app:
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mySocket = myDevice.createRfcommSocketToServiceRecord(MY_UUID);
mySocket.connect();
toast = Toast.makeText(context, "Connection established", thisClass.duration);
toast.show();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mySocket.close();
toast = Toast.makeText(context, "Connection not established", thisClass.duration);
toast.show();
} catch (IOException closeException) { }
return;
}
Where is the problem or what possibly i am missing in it. And also i am having ambiguity in the understanding of socket.connect() method. Kindly help me in this regard.
I just finished working on a similar application and had problems connecting. It would help to see a bit more of your code but the excerpt above looks like the example I was following. I would start by checking that the MY_UUID exists on the PC that you are trying to connect to.
I have posted my example, both the client and server, on my blog at http://digitalhacksblog.blogspot.com/2012/05/android-example-bluetooth-simple-spp.html.
Hope this helps.
I'm trying to connect to a simple Java server on my computer (in the future a true server, but I'm just learning how to program with sockets first. When I try to connect, the application on the phone throws an IOException. However, on the emulator, it does NOT.
I do have:
< uses-permission android:name="android.permission.INTERNET"/>
included in the manifest. And here's the code block that's executed when I hit open:
try {
responseField.setText("Opening socket...");
Socket socket = new Socket(getIP(),Integer.parseInt(getPort()));
responseField.setText("Socket opened. Initializing out...");
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
responseField.setText("Done. Initializing in...");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
responseField.setText("Done.");
} catch (NumberFormatException e1) {
responseField.setText("NumberFormatException");
} catch (UnknownHostException e1) {
responseField.setText("UnknownHostException");
} catch (IOException e1) {
responseField.setText("IOException");
}
Are you making sure that the server end uses a ServerSocket and uses the ServerSocker.accept() method?
So it seems that a weak Wi-Fi signal is causing error. I tried to surf the web (Google, CNN, etc.) afterward, and I could not. So I will just have to test on the emulator for now, or in a stronger signal. Thanks
If you were able to connect to the web before (I am assuming) but not after, then its not a problem with the wifi strength. Also depending on place you are surfing, the wifi router may have been configured not to allow such connections. Try to ping your server IP using a different computer within the same network and see whether you can ping. Emulator will work since the server is running on the localhost.