I am trying to read values from a weighing machine connected to bluetooth module(M143 RS232 Bluetooth Serial Adapter purchased from eBay).I am able to connect the device and i am getting Socket object.But the InputStream is blocking and not able to read data from the stream(inputstream.available() is always returns zero).There is no issue when i write something to the OutputStream.I tried using BufferedReader but no change.Following is the code i tried.
InputStream inputStream = socket.getInputStream();
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line).append('\n');
}
//code is not reaching here it is blocking in the while loop
if(outputStream!=null){
outputStream.flush();
outputStream.close();
}
Are you opening sockets for connection in different threads. There should be 3 threads for connection. This is valid for non-Bluetooth LE. Bluetooth Connectitivty
Connection Thread
Accept Thread
Connected Thread
If you use these threads, you will be able to get data using connected thread and you can pass data to main thread using handler, callback or BroadcastReceiver. I use all three of them seamlessly.
If you wish to check whether it works or not, download Bluetooth Terminal app from Play Store. It exactly uses Threads and Handler to display data. You can find one of the Bluetooth Terminal source code too. One of them is open source.
For BLE you can try this link. There are working samples associated with guides.
If you want to be sure your BT device works, download a BT terminal program pc or/and Android and test your device.
It is important to note that .read() or .readline() only halts reading when there is a newline or EOF, end of file.
However, socket connection does not have EOF unless the socket transfer is done.
so you could do the two following cases:
1) Change the other side(weighing machine in your case) to add \n or \r after each data transfer to let the Android side know one full set of data was sent.
This keeps the benefit of socket connection.
and you could do
while ((line = r.readLine()) != null) {
//do what you want to do with line
//... you dont need string builder in this case
}
2) Halt each connection from the other side after each data transfer. This is not recommended because it is not anymore a socket transfer when you cut after every data transfer. Also it might cause TIME_WAIT and hinder further connections.
I was able to do the first case to solve my problem when I was in your shoes.
The execution blocking in reading of InputStream is because of if no bytes are coming from the Socket,the existing thread will wait for a byte to come from the Socket.
Communication via bluetooth with other android devices or microcontrollers such as Arduino Android Smooth Bluetooth
// This thread runs during a connection with a remote device.
// It handles all incoming and outgoing transmissions.
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
Related
I am trying to establish Bluetooth connection between an Android device with other mobile phone over Handsfree profile. I am using following code -
private static final UUID MY_UUID = UUID.fromString("0000111F-0000-1000-8000-00805F9B34FB"); // UUID for Hands free profile
// Some code...
// Get Bluetooth Adapter.
m_oBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Some code...
// For paired BT device, getting a connection established.
if(null != m_oBluetoothDevice)
{
if(BluetoothDevice.BOND_BONDED == m_oBluetoothDevice.getBondState())
{
try
{
m_oBluetoothSocket = m_oBluetoothDevice.createRfcommSocketToServiceRecord(MY_UUID);
m_oBluetoothSocket.connect();
Log.i(TAG, "Socket Connected");
}
catch(Exception e)
{
if(null != m_oBluetoothSocket)
{
Log.i(TAG, "Closing socket");
try
{
m_oBluetoothSocket.close();
}
catch (Exception e1)
{
Log.i(TAG, "Error while closing socket : " + e1.getMessage());
}
}
}
}
}
I can create RFCOMMSocket using this code.
Now I want to send AT commands based on Bluetooth Hands-Free profile. e.g. If other mobile phone receives a phone call, my Android device can reject this call by sending AT command- "+CHUP". I am not sure whether this is possible or not.
At this point, I am stuck. I have read Bluetooth APIs where I found -
BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT
Can we use this Intent for sending AT commands? Is this a proper way to send AT command based on Bluetooth Hands-Free profile? Please someone help me out and give me proper direction.
Any input from you all will be great help for me.
Thanks in advance.
You need to create InputStream and OutputStream so you can talk to the phone:
mmInStream = m_oBluetoothSocket.getInputStream();
mmOutStream = m_oBluetoothSocket.getOutputStream();
To setup the HFP connection you start to send:
mmOutStream.write("AT+BRSF=20\r".getBytes());
Where 20 is code for what you support of HFP.
And to read from the phone:
buffer = new byte[200];
mmInStream.read(buffer);
command = new String(buffer).trim();
So now you can talk beetwen the devices and you can read more about the Handsfree profile on https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=238193
Adding reference to AT commnads
http://forum.xda-developers.com/showthread.php?t=1471241
http://www.zeeman.de/wp-content/uploads/2007/09/ubinetics-at-command-set.pdf
Iam trying to connect to a socket by using the connect method. Iam generating a String containing the UUID like this:
MY_UUID = UUID.fromString("45341da0-c9c1-11e1-9b21-0800200c9a66");
Then constructing a BluetoothSocket like this:
BluetoothSocket tmp = null;
I also want to connect to a specific device by its mac-address:
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice("00:1B:DC:0F:EC:7E");
and then making the bluetoothSocket
try {
tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Exception1: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
Just for to test I added a breakpoint where the tmp object is been initialized inside the try catch. But it's only containing NULL The remote device does support OBEX OPP, but this is just a layer above the RFCOMM in the bluetooth stack, so I think my device should support RFCOMM for connections. Can anybody tell me why my tmp object is set to null?
Is there anyway I can test whenever the socket is created?
I'am use TCP for connect my android phone with Windows 7 PC. When I'am send message phone-PC in LAN this system is work, as i`am use this system in Internet she is down because android app send me "time out". Why?
// The host name can either be a machine name, such as "java.sun.com", or a
// textual representation of its IP address
String host = "10.26.144.118";
int port = 20;
try {
Socket socket = new Socket(InetAddress.getByName(host), port);
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
// true for auto flush
writer.println("Hello World");
myView.setText("Send hello world");
} catch (Exception e) {
System.out.println("Error" + e);
myView.setText("Error" + e);
}
You are probably looking for port-forwarding
Your problem is that you mixed up the LAN (local area network) with the WAN (wide area network) aka the internet. Your personal LAN is protected from outside.
You need a static public IP or a DDNS (Dynamic DNS) solution e.g. dyndns. Than you have to forward the traffic from your public IP to you internal Server IP. See also thax's answer.
Than can your smartphone connect to your static public ip or to your DDNS address. Than should your app also work with the mobile network.
I want to make an android application that connects to a Wifi network, say network SSID = "ABC".Assume that it is connected to the Wifi ABC. After connecting to ABC, i would want my application to display the ips of all the android devices that are connected to the same wifi ABC network. How can i achieve that? Thanks
Check out the file: /proc/net/arp on your phone.
It has the ip and MAC addreses of all the other devices connected to the same network. However I am affraid you wont be able to differentiate if they are android phones or not.
You will want to use tcpdump to put the network card into promiscous mode and then capture packets to identify what other clients are on your network.
How to use tcpdump on android:
http://source.android.com/porting/tcpdump.html
You can run commands in your code like so:
try {
// Executes the command.
Process process = Runtime.getRuntime().exec("/system/bin/ls /sdcard");
// Reads stdout.
// NOTE: You can write to stdin of the command using
// process.getOutputStream().
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
// Waits for the command to finish.
process.waitFor();
return output.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
I am trying to communicate with a Bluetooth programmable Microcontroller. The Bluetooth device on the microcontroller communicates (specifically) on Bluetooth Serial COM Port number 4.
QUESTION: How can I get the Android App to read data from this COM port (number 4)?
I know the UUID is a well known unique ID,that works for this device, but I don't think that it has anything to do with specifying the COM port.
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
btSocket = btDevice.createRfcommSocketToServiceRecord( myUUID);
btSocket.connect();
valid.append( btDevice.getName() + "\n" + btDevice.getAddress());
north.append("Socket Connected");
InputStream mmInStream = btSocket.getInputStream();
OutputStream mmOutStream = btSocket.getOutputStream();
byte[] buffer = new byte[10];
int bytes;
StringBuffer str = new StringBuffer();
while (true) {
try {
mmOutStream.write("a".getBytes());
//Reads a # of bytes until the end of stream is reached
bytes = mmInStream.read(buffer);
//Transform to string
str.append(buffer.toString()+"\t"); //Clear the buffer
Log.e("DATA", "THE DATA: "+ str.toString());
south.setText(str.toString());
str.delete(0,str.length());
} catch (IOException e) {
break;
} }}
The COM port is something that exists only on the microcontroller, not the Bluetooth device attached to it. The Bluetooth device does not even know which COM port the microcontroller used to connect to it. The Bluetooth device's connection to the micro is via the TX and RX lines. The fact that they are attached to pins on the micro assigned to a specific COM port is irrelevant and unknown to the Bluetooth device.
I had this problem with a custom bluetooth device I built. Instead of using createRfcommSocketToServiceRecord in your connect thread, try something similar to the following:
public ConnectThread(BluetoothDevice device) throws
SecurityException, NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
mmDevice = device;
BluetoothSocket tmp = null;
// Force a BluetoothSocket for a connection with the
// given BluetoothDevice
Method m = mmDevice.getClass().getMethod("createRfcommSocket",
new Class[]{int.class});
mmSocket = (BluetoothSocket)m.invoke(mmDevice, Integer.valueOf(1));
}
Where my mmDevice is your btDevice.
This forces a socket connection between the unknown device and the smartphone. From what I've heard, there's an issue in Android connecting "non-similar" devices. Worth a shot.