How to connect with a Bluetooth device without pairing - java

I'm currently developping my first app in java.
This app requires a direct connection with my BL652, which doesn' t accept any kind of pairing option. That being said, I'm stuck with the code below, which still tries to pair with my bluetooth device instead of just connecting. Therefore, I wanted to know what am i supposed to do in order to make a connection that doesnt require pairing.
Thanks in advance for any response.
String mac_address = "DA:72:21:29:0F:F0";
private static final UUID MY_UUID = UUID.fromString("E54B0002-67F5-479E-8711-B3B99198CE6C");
lvNewDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BluetoothDevice device = (BluetoothDevice) mBluetoothAdapter.getRemoteDevice(mac_address);
try {
socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
} catch (IOException e) {
e.printStackTrace();
}

I'm not sure about connection to external hardware but it's definetly possible to connect 2 phones without pairing. I made it using Android Nearby Connections . And yeah it's basically working with BLE. As far as I know it's possible to connect to RaspberryPi using that API.

Bluetooth devices can be made to communicate with each other using master-slave configuration. I first tried with two BLE-HC05s, made one as master and the other as slave, and as expected the master is able to send data, slave is able to receive data, that can be seen using the Serial Monitor in Arduino IDE. I have developed a similar app, which connects to a BLE-HC05 device, sends and receives data. But since you are trying to get data or send data to the App on your phone, Android will not support such unpaired anonymous communications. If you are having trouble with connection or pairing Bluetooth device and your app, I may help you with that. But as far as Bluetooth communication without pairing is concerned, you may not be able to find a way.
Edit: The code to connect any bluetooth device, like BLE-HC06 as you have mentioned, is 1234 (Only if you have not changed it)

Related

Android 9 - Socket Connect TIMEOUT when Mobile data enabled

I have a deployed app that is failing on Android 9. Part of its function is to configure a module over an Access Point network to allow that that module to connect to the users home network.
I have code that detects and connects to the correct WIFI network, but when I attempt to open a socket to the device, it fails - only on Android 9 and only if mobile data is enabled. If I manually disable mobile data on the device everything runs fine.
Socket open() {
Socket sock = new Socket(Proxy.NO_PROXY);
try {
sock.bind(new InetSocketAddress(localIpAddress(), 50000));
} catch (IOException e) {
activity.logContent("Warning: Failed to bind socket : " + e.toString());
}
try {
sock.connect(new InetSocketAddress("192.168.17.1", 5555), (int)5000);
} catch (IOException e) {
// This catch fires when Mobile Data is on.
activity.logContent("Connected to " + activity.mWifiManager.getConnectionInfo().getSSID());
activity.logContent("Couldn't open socket : " + e.toString());
}
return sock;
}
I have tried this with and without the Proxy.NO_PROXY and with and without the bind() call. If the bind call is missing the error implies that the socket is attempting to connect over the cell network. (Note: activity.logContent() is an on-screen log so it is easier to see what is happening when not connected to a debugger).
Any ideas what is going wrong?
After a few days of imprecations I believe I have come to the identification of the problem and therefore to the solution:
The problem occurs due to some changes in the version of android (I presume to be 9.0 even if other changes had occurred on API 21), in particular on the creation of the socket, if the system detects that there is a "better" network (access to internet, high signal, etc, etc) socket creation refers to that network and no longer to the wifi network you would like.
I looked for ways to force the creation of the socket on the wifi network (which is the network I want) and the only way I found is this:
Simply put instead of:
Socket sock = new Socket ();
Do:
ConnectivityManager connectivity = (ConnectivityManager) MyApp.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null)
{
for (Network network : connectivity.getAllNetworks())
{
NetworkInfo networkInfo = connectivity.getNetworkInfo(network);
if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI)
{
if (networkInfo.isConnected())
{
Socket sock = network.getSocketFactory().createSocket();
}
}
}
}
Practically browse the networks present in the device and when you find your active wifi you do nothing but take advantage of this function to get the right socket for sure:
getSocketFactory().createSocket()
Now you have the working socket!
In my case it now works perfectly, if someone finds better solutions, it is welcome, but for now it is the only way I have found to make everything work as in the previous version of android.
In Android 9 there a security config about network: Android security config
Adding your domain in network_security_config might solve your problem. I had this in my network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">119.xxx.xxx.xxx</domain>
</domain-config>
</network-security-config>
I am not sure about the exact reason of why this is happening. However, when you are turning on your mobile data and you are only connected to the internet using your mobile data (considering your wifi is turned off), it gets the IP address from the cellular network which is no more connected in your home network. Hence, this is trivial to expect such timeout scenarios, because, it cannot reach the private IP addresses of your home network starting with 192.168.....
Now my confusion is that even if the mobile data is turned on, and both wifi and mobile data is turned on at the same time, the device should connect to the wifi as a default behavior.
Hence I would like to suggest you check the following.
Android 9 (Pie) introduces special Wifi preference, which prevents connecting to public networks automatically. You might consider checking the settings.
Please check the IP address of your device and check if it has some IP address starting with 192.168..... If not, then definitely, you are getting your IP address from your cellular network and hence it cannot reach your private IP addresses of the home network.

how would you give name to bluetooth service in android things?

I created one simple service in android things to use Bluetooth BLE.when I try to test it with NRF connect app it's visible as "unknown service".I want to give name something like "Speed Service".how would I do it?
This is a factor controlled by the scanning app you are using, not necessarily your Android Things device. Bluetooth LE doesn't send metadata like a "service name" over the air. Services are identified by their UUID alone. If your device implements one of the standard service UUIDs, a scanner app like NRF Connect will probably recognize and display the service type.
As another example, our Bluetooth GATT Server sample implements the standard Current Time Service by using the UUID adopted by the Bluetooth SIG for that service.
private BluetoothAdapter bluetoothAdapter = null;
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
void ChangeDeviceName(){
Log.i(LOG, "localdevicename : "+bluetoothAdapter.getName()+" localdeviceAddress : "+bluetoothAdapter.getAddress());
bluetoothAdapter.setName("NewDeviceName");
Log.i(LOG, "localdevicename : "+bluetoothAdapter.getName()+" localdeviceAddress : "+bluetoothAdapter.getAddress());
}
Reference: Change the Android bluetooth device name
Hope this case is similar and of use to you.

Arduino HC-05 Bluetooth module disconnects when sending data

I'm new to Arduino. I'm trying to build a program to control a breadboard through Arduino using the bluetooth module HC-05. At the moment I don't have anything on the breadboard and I'm just trying to test the connection. This is what I've done so far:
I put the module on the breadboard and I've paired it with the computer. When it's paired, the red led starts blinking slowly. I've connected the bluetooth Rx to Arduino Tx and Arduino Rx to bluetooth Tx following this tutorial: http://playground.arduino.cc/Learning/Tutorial01
I've also implemented both Java and Arduino programs following that tutorial. Here they are:
JAVA
public class Arduino extends PApplet{
public void connect(){
String[] serials = Serial.list();
Serial port = new Serial(this, Serial.list()[0], 9600);
port.write('H');
port.dispose();
}
ARDUINO
void setup() {
Serial.begin(9600);
Serial.println("Start");
}
void loop() {
if(Serial.available()){
int a = Serial.read();
Serial.print(a);
}
}
The Java part should send the letter H to Arduino and Arduino should detect that and print it on the Serial monitor. But what actually happens is that I send data, and the led on the HC-05 starts blinking faster (which means the connection is lost). Why does that happen? I'm pretty confused. For the communication I'm using the port COM6 and COM7. It depends on how it connects. To see what port to use I just run the Java program: if the port is not correct, it will just get stuck and send nothing.
Any help is appreciated. Thanks!
In the end, I've solved this problem by removing this line of code:
port.dispose();
It would never work with it because I was getting rid of the connection. I don't know what I was thinking at the time I did that. That was very silly of me.
Ok so I had this problem.
If you are using the L293D motor shield, you'll be running the arduino of the same power supply, which I think must affect the power output the the bluetooth HC05 module.
Take out the jumper plug on the L293D motor shield, and run the arduino of a separate power source (e.g PP3 battery) and the problem disappears, OK.

Java desktop bluetooth client can not find services

I am new to bluetooth programming, so please keep that in mind.
I am trying to connect to a pulse sensor from a desktop pc, specifically the Zephyr HxM BT. I am not using any device specific drivers, the Java bluetooth library I'm using is Bluecove, and my bluetooth stack is BlueSoleil.
From my understanding, the way I proceed is
1) Scan for BT devices
public void startSearch() throws BluetoothStateException{
System.out.println("Inquiry started");
localdevice.getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, this);
}
This works fine, it discovers my pulse belt and calls
public void deviceDiscovered(RemoteDevice arg0, DeviceClass arg1)
2) Search a device for services
Once a device has been discovered, it should be added to the DiscoveryAgent's list of cached devices, this is my first problem as the cache (and preknown devices) is always empty even though I've discovered my belt.
So the way that I do this now is to either keep my own list of devices, or simply start a service search directly from deviceDiscovered.
I am still a bit unsure if I'm using the correct parameters, but from reading the BT device manual and the javax.bluetooth documentation on DiscoveryAgent.searchServices:
public int searchServices(int[] attrSet,
UUID[] uuidSet,
RemoteDevice btDev,
DiscoveryListener discListener)
throws BluetoothStateException
My code:
public void searchServices(RemoteDevice device){
UUID[] uuidSet = new UUID[1];
uuidSet[0]=new UUID("1101",false); //Serial Port
System.out.println("Searching for services on " + device.getBluetoothAddress() );
try{
agent.searchServices(null,uuidSet, device,this);}
catch (BluetoothStateException e){
System.out.println("BluetoothStateException caught.");
}
}
I've set the attributes parameter to null, because the documentation states that this will have it search for services with the default attributes, however I've also tried to use only ServiceID (0x0003) as attribute with no luck.
This is where I'm stuck, I pass the correct BT device into the function, and it starts searching but never give me any results, it just searches forever for all I know, no exception, no calls to
public void servicesDiscovered(int arg0, ServiceRecord[] arg1)
or
public void serviceSearchCompleted(int arg0, int arg1)
So I guess my questions are:
- Am I doing something wrong? Any suggestions?
- What are the other approaches to connecting to a BT device, and what
information do I have to know about the device to do that?
Here is some information that I think is relevant from the device manual:
The following steps have to be undertaken to connect to a HxM device.
1) Activate the Bluetooth service of the device/computer wanting to connect to the HxM
2) Scan for Bluetooth devices in range
3) Pair with the HxM device found in range
4) Discover Services of Paired HxM
5) Connect to serial port of HxM device
The diagram above shows that the Bluetooth HxM typically communicates with a mobile device over the Bluetooth
link. The HxM only supports one link at a time and uses the Bluetooth SPP (Serial Port Profile) to communicate
with other devices with the following low-level protocol:
• 115,200 baud
• 8 data bits
• 1 stop bit
• No parity
Any suggestions are very much appreciated
edit: I just want to add that I'm testing the code with a console input loop, so the program is not immediately terminated after calling searchServices, it should have time to complete unless I'm misunderstanding async tasks
I just wanted to update this and say that I found the problem, it seems that I had to use a short UUID instead of a long. I should have tried both of these options before I deemed myself stuck, but I didn't think it would make any difference.

Bluetooth android server client with a headset

I'm trying to create a server on android that will listen on incoming connections ,such as a specific headset i have.
I've read many tutorials, posts in StackOverflow and the one from Android|Developer , and i don't seem to understand a few things .
1) UUID , is it a specific address for each Bluetooth device ? or is it a shared key that need to be in the server and the client in order to create a connection ? my guess is the latter cause there the MAC address as well ...
2) When i pair my Headset with my phone , does the headset saves the MAC\UUID of the last paired device ?
3) Does the Bluetooth chips even works in that way ? The phone connects immediately to a paired device as it turned on, So my guess is that it opens a Socket for each paired device and waits for it to turn on , is that true ?
4) Is it possible to accomplish what im trying ? Meaning creating a BluetoothServerSocket that will accept a connection from the head set ?
code example for the server side:
//This may b needs to be the UUID of the headset ? or special one ? or what ?
UUID myUUID = UUID.fromString("0000111e-0000-1000-8000-00805f9b34fb");
private final BluetoothServerSocket mServerSocket;
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(Activity.APP_NAME, myUUID);
mServerScooket = tmp;
//Im hoping that this will block until the specific headset will be turned on
socket = mServerSocket.accept();
Thanks in advance.
1) UUID ,is a specific ID for Bluetooth communication. When you create your bluetooth socket in Android, listenUsingRfcommWithServiceRecord(Activity.APP_NAME, myUUID); ask Android to redirect bluetooth connection which match with the UUID to your app.
2) I'm not sure. It depends on the type of connection the headset can make. When you want to use it, do you need to select it in Android, or you can just put it and it works ?
3) I don't know. But you can have a look to Android source code ;)
4) If the bluetooth headset can create a connect socket, yes, it is possible
Hope this helps ;)
1) yes UUID is specific to each device and in order to connect to a device you need to have its UUID.
as shown in the Bluetooth chat example by Android SDK
2) depends on the hardware for example
chip sets like the HC-06 does saves the last paired device UUID
while the HC-05 dose not ...
3) The headsets that Ive tested (Samsung made) Acts as a server.
so by initiating a BluetoothSocket with the UUID of the headphone u can connect to it.
4) Yes it is possible to connect to a Bluetooth head set answered in the post : Using the Android RecognizerIntent with a bluetooth headset
Special notes :
Best way to listen to oncoming connections without any wakelocks that I found is by registering the BluetoothDevice.ACTION_ACL_CONNECTED Broadcast and check the name\mac\UUID of each incomming connection.
Thanks to Hoan Nagayu for the help.

Categories

Resources