I want the connected device to get BluetoothDevice device information without scanning Bluetooth, so I store all Bluetooth-connected devices.
However, while other devices behave as expected, one type of Bluetooth devices will lose their paired information when the phone is rebooted.
Do anyone know why this may happen or have an alternative way to obtain Bluetooth Device information without scanning?
You can use BluetoothAdapter.
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(mac);
device.connectGatt(mContext, false, mGattCallback);
// TODO your code
If the bluetooth device is not around, in BluetoothGattCallback's onConnectionStateChange will report BluetoothGatt.STATE_DISCONNECTED.
BluetoothDevice's creator has packages scope. But the source code of BluetoothAdapter's getRemoteDevice is:
public BluetoothDevice getRemoteDevice(String address) {
return new BluetoothDevice(address);
}
Related
I have to connect at least two devices to one Android device. But I don't know how to connect multiple connections and multiple command send. plz help me... i really don't know that....
I just can connect one BLE device to One Android device.
first, i connected two devices(same UUID, different address) in one Service like example
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice("aa:12:12:33");
mGatt = device.connectGatt(mContext, false, mGattCallback);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice("bb:18:66:44");
mGatt = device.connectGatt(mContext, false, mGattCallback);
i can listen to each device action(they have a button), GattCallback's callback comes from two devices action, but i can't send BluetoothGatt.writeCahracteristic to two devices.
I'm not sure, but i solved this problem. Before i tried to use one Service(Android Component) but i used Service each BLE Device. but i think this is not solution, because if i have to more BLE device, I should to prepare maximum Service Component.
I want to connect my tablet to my phone using WiFi direct in order to send some data like pictures etc from my phone to tablet.
But I do not want my phone to discover it first i.e I don't wanted to use discoverPeers() method of WiFiP2pManger.
How can I achieve this goal?
In your phone, use createGroups(). This makes your phone become the groupOwner. Then call discoverPeers() in your tablet, it will find your phone without your phone calling discoverPeers().
In your phone:
wifiP2pManager = (WifiP2pManager) context.getSystemService(context.WIFI_P2P_SERVICE);
channel=wifiP2pManager.initialize(context,context.getMainLooper(),null);
wifiP2pManager.createGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.i(TAG,"Creating p2p group");
}
#Override
public void onFailure(int i) {
Log.i(TAG,"Creating group failed, error code:"+i);
}
});
In your tablet, discover peers, request peers and connect peers as normal
In order to establish a WiFi Direct connection both phones should be running WiFi Direct discovery. In other words, they will see each other when they are both scanning for WiFi direct connections at the same time. This is because the way WiFi Direct works is that when phones are scanning for WiFi Direct connections, they will negotiate with the other peers for the role of Access Point or Slave device. Hence both need to call discoverPeers() to become discoverable themselves and find nearby devices.
In your use case you could even build your application using wifi hotspot
This solution doesn't work. In Android both need to be on discovery mode in order to connect.
Is it possible to automatically connect to Bluetooth Low Energy (BLE) devices?
The Android documentation indicates that the [BluetoothDevice.connectGatt()](https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback)) has a autoConnect parameter:
boolean indicating whether to automatically connect to the BLE device
as soon as it becomes available
However, to call this, you need a BluetoothDevice first. AFAIK the only way to get this is by scanning available devices. Setting up a scan every time to connect to a device doesn't seem like a desirable way. Also, I tried using nRF Control Master Panel to connect to my peripheral using the autoConnect = true, but this does not connect to the device. Connecting without the autoConnect however does make it connect, and I've managed to read and write data from and to my peripheral this way with success.
The general way in Bluetooth to have two devices paired. However, searching for my BLE device and using BluetoothDevice.createBond() does not seem to work. In my ACTION_BOND_STATE_CHANGED-callback, the EXTRA_BOND_STATE and EXTRA_PREVIOUS_BOND_STATE just go from BOND_BONDING to BOND_NONE and back. I don't read out an error or anything - so maybe I'm missing something here. Here's the callback:
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
Log.e(TAG, "prevState " + prevState + ", state " + state);
}
}
};
So this type of bonding does not seem to work.
My question is: am I doing something wrong for pairing or the autoConnect? Or is how I currently have it working the only correct way? It seems like a real pain (and battery-drain) to have to scan for devices every time, see if the device is there, if so read data and check back tomorrow, otherwise check back in an hour or so. The point of Bluetooth is that it should pair directly whenever it is near, isn't it?
It does work without rescan. You do not need pairing at all. Just call BluetoothGatt.connect() again for gatt object you aquired from first connection.
You will receive onConnectionStateChange event in your BluetoothGattCallback as soon as ble device will be available again. If you use autoconnect option, you don't even need to call BluetoothGatt.connect() method. Just monitor your cllback, and don't forget to close BluetoothGatt with close() if you don't see any connection for too long.
And yes, to obtain first connection you should scan for ble devices with BluetoothAdapter.startLeScan, not the common bluetooth devices scan.
I try to develop a simple android app with a ble device.
I found many source code from the Intenet. However, both of them were start from scanning a list of available ble device.
As I have MAC address of the device,UUID of service and characteristic.
How can I connect to the known device and read one specific characteristic directly??
To connect a specific Bluetooth Device which has details like MAC address of the device, UUID of service and characteristic etc. you already know. To do this you need a BluetoothDevice object to make a call like this:
yourBluetoothDevice.connectGatt(getApplicationContext(), false, bleGattCallback);
So for this (yourBluetoothDevice) you have to start the scan at first to get same device object to connect by comparing it's MAC address. However, you got that same device object in onLeScan callback just stop scanning and make a connection with the same device.
Note: Making a connection should be on UIThread(Either using Handler, runOnUIThread or mainlooperThread) otherwise it will give issue in some devices for 'Fail to register callback'
Here yourBluetoothDevice is the device object reference with you want to make a connection.
bleGattCallback is the registered new BluetoothGattCallback() callback for connection status, discovered services, characteristics read and write etc.
Take a look at createInsecureRfcommSocketToServiceRecord. Something like this:
UUID uuid = UUID.fromString("<Your UUID>");
BluetoothSocket socket = yourBLEDevice.createInsecureRfcommSocketToServiceRecord(uuid);
Method m = yourBLEDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
socket = (BluetoothSocket) m.invoke(yourBLEDevice, 1);
If you already know the mac address, you can try something like below:
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mMacAddress);
final BluetoothGatt mGatt = device.connectGatt(getApplication(), false, gattCallback);
Is it possible to connect with other Bluetooth LE device with out scanning.
I am working on app when bluetooth is ON and then automatically received the notification when I enter in any marketPlace that Beacon device(basically Bluetooth LE) is in your range. without my scanning Bluetooth Le. My Bluetooth is just ON. no scanning.
Because our requirements are that bluetooth doesn't scan just on, when ever new BLE is in range show alert or any notification.
I implement some scan method
startScan(){}
stopScan(){}
#Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {}
but i don't want that i directly want to get connection message.
Please help me in form of pieces of code and also with little bit explanation
Thanks
You can use BluetoothAdapter.
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(mac);
device.connectGatt(mContext, false, mGattCallback);
// TODO your code
If the bluetooth device is not around, in BluetoothGattCallback's onConnectionStateChange will report BluetoothGatt.STATE_DISCONNECTED.
BluetoothDevice's creator has packages scope. But the source code of BluetoothAdapter's getRemoteDevice is:
public BluetoothDevice getRemoteDevice(String address) {
return new BluetoothDevice(address);
}
Do you just want to discover devices that support a particular service? There is an overload startLeScan(UUID[], ...), where you can pass the UUID's of the services that you are interested in.
Otherwise, if you just want to connect to a device of a known BT address, you maybe able to create a Bluetooth device object with that address and call connectGatt() on it. Just an idea, not sure if this would work :-)
Creating a bluetooth device object with address is not possible!
BluetoothDevice's creator has packages scope. so you can not create BluetoothDevice.
And although BluetoothDevice implements Parcelable, it cannot be created from a file.