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
Related
Greetings Stack Overflow community,
I am writing an android app that reads some data off of an HC05 bluetooth module.
I am just trying to read one byte but it just hangs there for a few minutes before it crashes. Maybe its a hardware problem, but perhaps there is some error in my code I do not see. If anybody has a clue as to why I would not be able to read from this module I would greatly appreciate the input.
Thanks!
for (BluetoothDevice iterator : bondedDevices) {
if (iterator.getName().equals("HC-05")) {
BluetoothDevice device = iterator;
try { btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);} catch (IOException ex) {}
try {btSocket.connect();} catch (IOException ex) {}
if (btSocket.isConnected()) {
Toast.makeText(getApplicationContext(), "Connected to HC05", Toast.LENGTH_SHORT).show();
//Write 'r' to arduino to tell it to send data.
try {
outStream = btSocket.getOutputStream();
outStream.write('r');
} catch (IOException ex) {}
int byteCount = 1;
byte[] rawBytes = new byte[byteCount];
try {
inputStream= btSocket.getInputStream();
int a = inputStream.read(rawBytes, 0, 1);
}
Did you try using a Bluetooth terminal app for android? This way you can find out if it's a hardware or software issue.
You could try this app:
https://play.google.com/store/apps/details?id=Qwerty.BluetoothTerminal
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)
What I DO :
Write an upload program using java.net.Socket at Android Mobile
What I WANT:
Connect the Server, When IOException happens(such as the bad network state,no network etc.),try to connect the server three times
What The Question:
Close the WIFI or Mobile GPRS and just run it, No IOexception happened and APP just stop at this point long long time.
Just See My Code:
try {
do {
socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(API.UPLOAD_SERVER, API.UPLOAD_PORT);
socket.setPerformancePreferences(1, 0,0);
socket.setSoTimeout(1000);
socket.connect(socketAddress, 2000);
attempt = 3;
} while (attempt < 3);
mListener.onStart();
} catch (SocketException e) {
Log.e("UploadTask","exception");
return;
} catch (UnknownHostException e) {
return;
} catch (IOException ioe) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return ;
}
attempt++;
if (attempt == 3) {
return;
}
}
Help Me or ...:
I hope someone can help me,I will wait your answer online, Thanks.
you have nothing output or exception if you close WIFI or GPRS. Does this mean you app will run over or you code will stay in one sentence,for example, the "connect" method?
I have a suggestion. If you want to explore the API of android, that's OK. OR
Maybe you can test Connectivity before your socket connect.
private boolean isOpenNetwork() {
ConnectivityManager connManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if(connManager.getActiveNetworkInfo() != null) {
return connManager.getActiveNetworkInfo().isAvailable();
}
return false;
}
hope this can help..
PS: I have no idea about the direct solution to your question, for I have no idea about the socket realize detail. Maybe someone else can explain it.
Assuming that the "connect" method succeeds (which can happen), the API is build in a way that you get IOException(s) when actually reading/writing to the streams of the socket.
socket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(API.UPLOAD_SERVER, API.UPLOAD_PORT);
socket.setPerformancePreferences(1, 0,0);
socket.setSoTimeout(1000);
socket.connect(socketAddress, 2000);
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// Now for example, if you want to read some data
int data;
try( data = is.read() ){
// Usual processing
} catch( IOException ){
// Disconnected... try reconnecting etc.
}
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
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