Bluetooth works one way only - java

I am very new to android and java so be gentle :)
I'm trying to connect two phones via bloototh.
i am making both phones to listen of incoming calls by creating serversocket, then initializing connection from one phone (as a client). funny part is that when I try to make my LG (android version 2.3.4) to connect HTC (android 2.2.1) everything works fine, but when i try to make HTc phone to connect as a client i get no result. Debugger shows that HTC fails at mmSocket.connect(); and executes catch (IOException connectException). My code is basicly copy/paste from android bluetooth tutorial. Any suggestions why phones behaves differently? Connect thread:
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
BtAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect(); **HTC phones fails here and goes to CATCH block**
// make info message
Message msg = mainHandler.obtainMessage();
Bundle bundle = new Bundle();
String btnTxt = "Connected";
bundle.putString("myKey", btnTxt);
msg.setData(bundle);
mainHandler.sendMessage(msg);
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
ConnectedThread conThread = new ConnectedThread(mmSocket);
conThread.start();
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}

There may be in issue with
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
on your HTC 2.21 device. Check what features the HTC device's Bluetoth adapter supports, that could be related to why it is failing with your program.
"Use this socket only if an authenticated socket link is possible.
Authentication refers to the authentication of the link key to prevent
man-in-the-middle type of attacks. For example, for Bluetooth 2.1
devices, if any of the devices does not have an input and output
capability or just has the ability to display a numeric key, a secure
socket connection is not possible. In such a case, use {#link
createInsecureRfcommSocketToServiceRecord}. For more details, refer to
the Security Model section 5.2 (vol 3) of Bluetooth Core Specification
version 2.1 + EDR."
http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createRfcommSocketToServiceRecord%28java.util.UUID%29

Related

How to handle InputStream and OutputStream via Bluetooth in Android

I'm developing an Android app that handles an alarm system made with an Arduino.
I have to handle InputStream from the Arduino and OutputStream to Arduino. First, I used a thread to initialize the connection for the Bluetooth socket and it works, but inside the thread I have to call a sort of Service/Thread that could make me handle streams from and to Arduino but I don't know how to do it.
The fact is that the hypothetical service has to listen continuously if there are streams, it has to stop only when I want and not after a certain period of time. Thanks for the help! Here is the code related to the Bluetooth socket connection:
public class ConnectThread extends Thread {
private final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
while (!Thread.currentThread().isInterrupted()) {
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
Log.i("Log", "Socket closed");
this.interrupt();
Log.i("Log", "Thread interrupted");
} catch (IOException closeException) {
}
}
//I think here I have to start a sort of Service/Thread..
}
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
this.interrupt();
Log.i("Log", "Thread interrupted");
} catch (IOException e) { }
}
}
I have implemented a similar algorithm, that I basically copied from the BluetoothChatSample, that for example comes with android studio samples, too.
You can see all the concepts, how to receive and send a String in the sample and they have added permissions, dialogs to ask the user about enabling Bluetooth and such, too.

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)

Create a socket for 4.0 bluetooth transmission

I'm developing an Android app than can transmit data to a 4.0 Bluetooth serial device. I'm guiding by LeGatt android sample project (http://developer.android.com/samples/BluetoothLeGatt/index.html). In this project, they connect to the device, but nothing about transmission data.
For 2.0 bluetooth I can create a Socket, InputStream and OutputStream to transmit the data, something like this:
protected BluetoothSocket mySocket = null;
private InputStream MyInStream;
private OutputStream MyOutStream;
try {
Method m = mBluetoothDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmp = (BluetoothSocket) m.invoke(mBluetoothDevice, Integer.valueOf(1));
} catch (Exception e) {
textViewLog.append("\n"+"CONNECTION IN THREAD DIDNT WORK");
}
mySocket = tmp;
try {
mySocket.connect();
} catch (IOException e) {
textViewLog.append("\n"+e.getMessage());
textViewLog.append("\n"+"CONNECTION IN THREAD DIDNT WORK 2");
}
try {
MyInStream = mySocket.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
try {
MyOutStream = mySocket.getOutputStream();
} catch (IOException e) {
textViewLog.append("\nERROR: "+e.getMessage());
}
try {
MyOutStream.write((letra+"\r").getBytes());
} catch (IOException e) {
textViewLog.append("\nERROR: "+e.getMessage());
}
But in 4.0 Bluetooth I can't create the Socket, because this method doesn't works
try {
Method m = mBluetoothDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmp = (BluetoothSocket) m.invoke(mBluetoothDevice, Integer.valueOf(1));
} catch (Exception e) {
textViewLog.append("\n"+"CONNECTION IN THREAD DIDNT WORK");
}
Can someone help me to reach the data transmission using my 4.0 bluetooth device.
Android BLE works entirely different from the Bluetooth stack, read about BLE in Wikipedia.
To send a data using BLE, you need to place your data in characteristics and send it using the gatt!
1st, you need to check your BLE device, which characteristic is used for sending data and used that characteristics for sending data!
byte[] data; //Place your data into this array of byte
characteristic.setValue(data);
gatt.writeCharacteristic(characteristic);
Please take note that Android BLE stack is buggy, you can only writeCharacteristics once at a time, as mention in the link below!!
You can check this post about Android BLE, it will give you a clear understanding of the how the Android BLE callbacks work!
Android BLE, read and write characteristics

Bluetooth Server Android - Client Java Bluecove. UUID?

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

Bluetooth socket freeze phone

I am developing an application for Android. This app should communicate with a Bluetooth (BT) device (sending some bytes). I have a problem with debugging/running this app on my device (Samsung Galaxy mini). When I create a BT socket and stop debugging, phone freeze and I have to restart it by getting out the battery. In case of running this app (from Eclipse) everything is OK, but when I try to run it again, phone freeze and app is not installed. If I try to unninstall this app manualy before second run, phone freeze again. Here is a problematic code:
private final BluetoothDevice mmDevice;
private UUID uuid;
public ConnectionThread(BluetoothDevice device) {
Log.d(TAG, "create ConnectionThread");
uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = mmDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) { }
mmSocket = tmp;
socketConnected = true;
}
This is a constructor of thread. When I comment the line
tmp = mmDevice.createRfcommSocketToServiceRecord(uuid);
the phone doesn´t freeze so problem is with creating socket (not connecting). Restarting phone after each debugging or running is pretty annoying and I have to do a lot of work yet.
If I run this app from a phone (disconnected from Eclipse), it works without any problems. Any ideas where could be a problem or how to fix it? Thank you.
I am using SGSIII mini as well for development. The following code works well for me:
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
//tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(LOG_TAG, "create() failed", e);
}
mmSocket = tmp;
Main.myBluetoothSocket = mmSocket;
Main.myBluetoothDevice = mmDevice;
}
#Override
public void run() {
Log.i(LOG_TAG, "BEGIN mConnectThread");
setName("ConnectThread");
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(MESSAGE_TOAST);
Log.e(LOG_TAG, "Attempting connection to " + mmSocket.getRemoteDevice().getName());
String ss = "Attempting connection to " + mmSocket.getRemoteDevice().getName();
Bundle bundle = new Bundle();
bundle.putString(TOAST, ss);
msg.setData(bundle);
mHandler.sendMessage(msg);
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
Log.e(LOG_TAG, "*+*+*+* Connection Failed");
connectionFailed();
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(LOG_TAG, "unable to close() socket during connection failure", e2);
}
// Start the service over to restart listening mode
BluetoothCommandService.this.start();
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothCommandService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(LOG_TAG, "close() of connect socket failed", e);
}
}
}
I am also facing same problem you can use Reflection method it will work
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
BluetoothSocket socket = socket = (BluetoothSocket) m.invoke(device, 1);

Categories