Bluetooth Server Android - Client Java Bluecove. UUID? - java

I'm writing an application to communicate between my smartphone and a computer using a bluetooth device.
I'm using Bluecove to manage the bluetooth on the computer, and the android API for my android device.
However, when I'm debugging, nothing happens. I think that the problem is that the UUID is wrong. I'm not sure how to get the devices to identify each other, in order to establish a connection.
I have read some other "questions" about those tags, but what I've tried didn't fix my problem:
Simple Bluetooth data receiver Android
Android: obtaining uuid of a bluetooth device
Etc...
Here's what I've written so far:
For tho android (Server) (This is the function that will make the connection)
public void connectSocket(){
blueAdapter.cancelDiscovery(); // Cancel discovery because it'll slow down the connection
final BluetoothServerSocket serverSocket;
BluetoothServerSocket sSocket= null;
try{
sSocket = blueAdapter.listenUsingRfcommWithServiceRecord("BluetoothJANE", MY_UUID);
}catch(IOException e){}
serverSocket = sSocket;
Thread acceptThread = new Thread(new Runnable() {
#Override
public void run() {
BluetoothSocket socket = null;
while(true){
try{
socket = serverSocket.accept();
}catch(IOException e){
break;
}
if(socket != null){
try{
iStream = socket.getInputStream();
oStream = socket.getOutputStream();
} catch(IOException e){}
}
}
}
});
acceptThread.start();
}
For java app on PC (This is the constructor of the class (it's on an independent thread) that will manage the bluetooth connection)
public ModuleBluetooth() {
StreamConnectionNotifier notifier = null;
StreamConnection connection = null;
try {
blueDevice = LocalDevice.getLocalDevice();
blueDevice.setDiscoverable(DiscoveryAgent.GIAC);
String url = "btspp://localhost:" + MY_UUID.toString()
+ ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier) Connector.open(url);
} catch (BluetoothStateException e) {
System.out
.println("ModuleBluetooth: Error getting the bluetooth device");
} catch (IOException e) {
}
System.out.println("waiting for connection...");
try {
connection = notifier.acceptAndOpen();
System.out.println("Conenction created");
} catch (IOException e) {
System.out.println("Can not create the connection");
}
}
Could somebody please help me? Any thoughts would be very much appreciated.
I have also tried to use some functions to acquire the UUID (in android) such as, [fetchUuidsWithSdp][2] (and the related functions) but eclipse doesn't recognize that functions (It seems that they don't exist in "my" API).
http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#fetchUuidsWithSdp%28%29

Try this example, http://luugiathuy.com/2011/02/android-java-bluetooth/ . I also had problem related to UUID, in this example, Converting UUID to 00001101-0000-1000-8000-00805F9B34FB worked out of the box. See this link: http://www.avetana-gmbh.de/avetana-gmbh/produkte/doc/javax/bluetooth/UUID.html

Related

socket() not throwing an exception despite server not running

I have written a client to run on an android device (android 6) and when the server is up and running it connects, however when the server is down the socket() call should throw an exception however it doesn't.
I originally tried it using the NDK and ran into a very similar issue (Android NDK socket connect() returning 0 when it should fail whilst on 3g).
I am assuming this is a bug with android at this point but any insight into a solution or work around would be much appreciated.
The code in question:
public class Client implements Runnable{
private Socket socket;
private InetAddress IP;
private int port;
public Client(int port){
try {
this.IP = InetAddress.getByName(server ip);
}
catch(UnknownHostException e){
Log.d("App1", "Unknown Host, connection failed");
System.exit(1);
}
this.port = port;
Log.d("App1", "initialised");
}
#Override
public void run(){
try {
this.socket = new Socket(this.IP, this.port);
Log.d("FiX1", "Connected");
listen();
}
catch(IOException e){
Log.d("FiX1,","connection failed");
System.exit(1);
}
finally
{
try{
socket.close(); // dispose
}
catch(IOException e){
System.exit(1);
}
}
}
public void listen() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
String cominginText = "";
try {
cominginText = in.readLine();
Log.d("FiX1",cominginText);
} catch (IOException e) {
//error ("System: " + "Connection to server lost!");
System.exit(1);
break;
}
}
} catch (IOException e) {
System.exit(1);
}
}
}
The best solution I could find was to manually send an acknowledgement from the server that a connection had been made, the client would retry the connection if it did not receive this message within a certain time after it claimed to have connected.
There is a difference between a TCP connection "close" vs "disconnect".
If you close the socket connection from server using socket.close() then you will get exception in client side, if you try to read from that connection or vice versa.
However, if one side just disappears(shut down the program) then the other side has no way of knowing that. So the other side will wait for response for read call.
The TCP protocol was designed to be reliable in hostile communication environments and it will not normally decide a connection is closed just because it has not heard from the other side for a while.

How to create a socket that listens a localhost port in Android

Before explain my doubt I want to mension that there're three "actors" in this enviorement:
A desktop program executed in some server
A person who uses this program remotely through a computer
And an Android tablet application that is connected with the computer via USB
When the person clicks on a link bar in this program that he is using remotely there's a shell script that sends a string to the person's computer port(e.g 1100). The requirement is: After recive this string from the desktop send it to the tablet.
So, what is the best way to recive this string from the desktop to the tablet?
Now there's a java daemon that is running in the desktop computer who is listening the 1100 port. This java app is working as a intermidiate between the desktop computer and the tablet, but I think that maybe there's a way to delete this daemon and just using the tablet to recive the computer data creating a socket.
You can also implement Java Sockets in Android. Like wise on Desktop Sockets in Android listens on ports but this will be accessed locally as there is no such way to assign static usable IP to an Android device.
There is another solution which is socket.io
Socket.io is one of the best socket library i have ever used. Implement socket.io on Node.js server and on Android simply connect to Node.js server and you can send same string to all connected users whether it is a Desktop or Android.
private class ServerThread extends Thread {
#Override
public void run() {
try {
serverSocket = new ServerSocket(portNumber);
while (true) {
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
LOGGER.error("Error on accept!");
}
// new thread for a client
new EchoThread(clientSocket).start();
}
}catch (Exception e) {
e.printStackTrace();
}
finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public class EchoThread extends Thread {
protected Socket clientSocket;
BufferedReader br = null;
public EchoThread(Socket clientSocket) {
this.clientSocket = clientSocket;
}
public void run() {
try {
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException e) {
...
}
isConnected = true;
while (isConnected) {
try {
receivedMessage = br.readLine();
if (!Strings.isNullOrEmpty(receivedMessage)) {
....
}
else {
//sleep 0,1s
//TODO (ver): Thread.sleep(100);
}
} catch (Exception e) {
if (e instanceof IOException) {
}
else if (e instanceof JsonSyntaxException){
}
else {
try {
Thread.sleep(2000);
} catch (InterruptedException inte) {
inte.printStackTrace();
}
}
}
if (//yourmessagecondition){
isConnected = false;
}
}
if (!isConnected){
try {
br.close();
clientSocket.close();
}catch (IOException ioe){
ioe.printStackTrace();
}
}
}
}
Hope this helps, it is working here... You probably find easier/simple examples on the Internet.
PS: If you are using a USB cable to communicate with the computer app, you can use the "adb forward" command, just google for some examples and accept this answer if it helped ;)

how to connect esp8266 softAp with android app

I want some brief idea/links for reference to start how to connect esp8266 router/access point with an android app.In esp8266 static ip is 192.168.4.1 wants to control led blink or other feautre with an android app .
how to make establish connection between esp8266 and android app .
On Android side it's just network communication without any features. Take a look at Official Documentation and tutorials like this. Everything depends on esp8266 firmware:
if it implements HTTP web server You can use HttpUrlConnection and GET or POST requests on Android side and corresponding script on esp8266 side;
if it implements ServerSocket You can use Socket connection an implement Socket Client on Android side.
Update:
Socket communication with esp8266 You should do it in separate (not UI) thread. Full example is something like that:
class SocketClientThread implements Runnable {
DataInputStream dis;
DataOutputStream dos;
String strResponseData;
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName("<address>");
clientSocket = new Socket(serverAddr, <port_number - 80 in your example>);
dos = new DataOutputStream(clientSocket.getOutputStream());
dis = new DataInputStream(clientSocket.getInputStream());
// now you can write data to stream
dos.writeUTF("Hello");
// you can also read data from stream
strResponseData = dis.readUTF();
} catch (UnknownHostException ignore) {
} catch (IOException ignore) {
}
finally{
if (clientSocket != null){
try {
clientSocket.close();
}
catch (IOException ignore) {
}
}
}
}
}
And than You can use SocketClientThread this way:
Thread socketClientThread;
socketClientThread = new Thread(new SocketClientThread());
socketClientThread.start();

How to programmatically connect to a Bluetooth device after it's already paired (bonded) in Android

I have been working on trying to get a Bluetooth device like a keyboard or a remote to connect to an android device. More specifically when this program runs for the first time it would scan for Bluetooth devices and attempt to pair and connect with one that it finds. I have tried seemingly every possible way to accomplish this but I am only able to pair the device, not connect it completely.
I have tried the examples in the Android Bluetooth guide and many others. One consistency is the javi.io error I get when the BluetoothSocket is calling connect.
java.io.IOException: read failed, socket might closed or timeout, read ret: -1
at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:505)
at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:482)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:324)
at BTConnectThread.run(BTConnectThread.java:61)
I have tried different UUIDs. Some I generated myself others I pulled from the devices. I also tried writing code assuming both are acting as servers that mirrors mostly what I am doing here and what is in the Android Bluetooth guide. have tried all variations of calling createBond() on the device. All attempts leave the device paired/bonded but not connected. Any help is greatly appreciated.
` public BTConnectThread(BluetoothDevice bluetoothDevice) {
BluetoothSocket tempSocket = null;
try {
// tempSocket = bluetoothDevice.createRfcommSocketToServiceRecord(WELL_KNOWN_UUID);
// tempSocket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(WELL_KNOWN_UUID);
//Magic?
Method method = bluetoothDevice.getClass().getMethod("createRfcommSocket",
new Class[]{int.class});
tempSocket = (BluetoothSocket) method.invoke(bluetoothDevice, 1);
} catch (Exception e) {
e.printStackTrace();
}
m_bluetoothSocket = tempSocket;
}
public void run() {
//cancel discovery
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter != null)
bluetoothAdapter.cancelDiscovery();
//TODO: Try brute force approach. Loop until it connects.
//TODO: Try a fallback socket.
try {
m_bluetoothSocket.connect();
Log.d(TAG, "Connection Established");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
Log.d(TAG, "Fail to connect!", connectException);
try {
m_bluetoothSocket.close();
} catch (IOException closeException) {
Log.d(TAG, "Fail to close connection", closeException);
}
return;
}
}
public void cancel() {
try {
m_bluetoothSocket.close();
} catch (IOException e) {
}
}`
Bluetooth connection require to create more than 3 threads, so you can try to use https://android-arsenal.com/details/1/1859.
Kotlin
Connect Function
fun connect(btDevice: BluetoothDevice?){
val id: UUID = btDevice?.uuids?.get(0)!!.uuid
val bts = btDevice.createRfcommSocketToServiceRecord(id)
bts?.connect()
}
Call this in main thread
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
val device = bluetoothAdapter.getRemoteDevice("your mac address")
connect(device)

Java Socket on Android, connection through 3G internet global ip

I have problems using Sockets on Android. I'm new to this topic so I try to achieve a simple chat, Android phone to another Android phone as a training.
I can use my code to create a ServerSocket and connect to it with another Socket from the same device ( An 'echo' example with only one client on one device works fine) I've done that also using two IP adresses on the same wifi (192.168...) but any tentative to connect a distant client using internet ip address using 3G connection fails with a
java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out)
What I do is, creating the ServerSocket (ServerConnect.java) :
private ServerSocket _mainServer = null;
private void initServer() {
try {
//port I use here is arbitrary: 8081
_mainServer = new ServerSocket(CONNECT_SOCKET_PORT);
} catch (IOException e) {
Log.w("ServerSocket", e.toString());
e.printStackTrace();
}
}
in the same class, in a separate thread I do this to wait for client connections :
while (running) {
GuestConnect ssc = new GuestConnect(_mainServer.accept());
ssc.setListener(this);
ssc.startConnection();
_clientSockets.add(ssc);
performGuestAdded("bra!");
}
it makes the server waiting for multiple client connection, so it can host more than two poeple in the 'chat room'.
The comunication server side is made from the local client callback and dispatch messages to all my guests (I'm still working on this part, its not really done yet but I don't think its relevant to my problem here) :
public void onMessageReceived(TBTGuestConnect sender, String message) {
for(TBTGuestConnect guestConnect : _clientSockets)
if(guestConnect != sender)
guestConnect.sendMessage(message);
}
Clients are store as 'GuestConnect' objects here is how I set them (GuestConnect.java):
public class GuestConnect {
private StringBuilder _currentMessage;
private BufferedReader _is;
private PrintStream _os;
private Socket _clientSocket = null;
private String _hostname;
private boolean _running = false;
public GuestConnect(String hostname) {
_hostname = hostname;
_currentMessage = new StringBuilder();
}
clientSocket initialisation (still GuestConnect.java):
private void initSocket() {
if(_clientSocket==null)
{
// Try to open a server socket on given port
// Here is the fail when I called it from another device
try {
_clientSocket = new Socket(_hostname, ServerConnect.CONNECT_SOCKET_PORT);
} catch (IOException e) {
Log.w("GuestSocket", e.toString());
}
}
// Create a socket object from the ServerSocket to listen and accept
// connections.
// Open input and output streams
try {
_is = new BufferedReader(new InputStreamReader(_clientSocket.getInputStream()));
_os = new PrintStream(_clientSocket.getOutputStream());
} catch (IOException e) {
Log.w("GuestSocket", e.toString());
}
}
again, in the same class there is the comunication part :
initSocket();
_running = true;
performConnectionStarted();
try {
while (_running) {
String received = _is.readLine();
_currentMessage.append(received);
if (received.contains(ServerConnect.CONNECT_SOCKET_MESSAGE_END)) {
String finalMsg = _currentMessage.toString().substring(0, _currentMessage.lastIndexOf(ServerConnect.CONNECT_SOCKET_MESSAGE_END));
performMessageReceived(finalMsg);
_currentMessage.setLength(0);
}
}
} catch (IOException e) {
Log.w("GuestSocket", e.toString());
performError(e);
} finally {
try {
_os.close();
_is.close();
_clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
performError(e);
}
_clientSocket = null;
}
I can then send a message from this method :
public void sendMessage(String toSend) {
if (_running)
_os.println(toSend+ServerConnect.CONNECT_SOCKET_MESSAGE_END);
else
throw new IllegalStateException("Send message : Connection isn't started !");
}
So the question is, what should I do to make this works using global internet ip addresses ?
And more generally, what it the technical difference between same wifi local ip address and internet ip adress ?
i'll start from the end because it's easier - local ip address is private, it's not valid (and not visible) out of your local network, someone out of your local network can't access it directly but you can access hosts with public ip addresses. because they are not universally visible private addresses are not unique, public ip addresses are unique and (normally) visible from any point on the internet. there's more on the subject http://en.wikipedia.org/wiki/Network_address_translation
when it comes to 3g networks take a look here Could I connect to my iphone using 3g ip? and here ServerSocket accept() not accepting connections on Android . so most probably it can't be done
Don't know if this would be of any importance to you but in our country most 3G accounts are blocked by the ISP from incoming connections. You have to apply to unblock the ports. Some ISP's won't unblock them and some will.
Found that out when I wanted to connect my DVR with a 3G modem.

Categories