Start the bonding process with a remote bluetooth device - android

I have managed to make an android device and scan and enlist all bluetooth devices in the area..I have the mac address of a remote device i just discovered in form of string and i want to start the bonding process with it.. i try BluetoothDevice object and then method createBond() but its not communicating with the remote device to pair..
Here is the code
class BluetoothM: AppCompatActivity{
// mac address of remote bluetooth device
string address;
//the discovered devices are listed in a ListView so i call a listview item click method to start pairing
private void Dlist_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
//the mac address has already been assigned in the OnReceive broadcast Receiver
if (e.Position == e.Id)
{
//Get the default adapter of the device
BluetoothAdapter adapt = BluetoothAdapter.DefaultAdapter;
//Get the remote device based on its MAC address
BluetoothDevice device = adapt.GetRemoteDevice(address);
//start the pairing process for the device
device.CreateBond();
}
}
}
//This class discovers bluetooth devices and pass MAC address to our string address for use in the listview click method
[BroadcastReceiver(Name = BluetoothDevice.ActionFound, Enabled = true)]
public class DeviceDiscovered : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
string ac = intent.Action; string name;
if (BluetoothDevice.ActionFound.Equals(ac))
{
BluetoothDevice device = (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);
//add bluetooth name and address if they do not already exist
if (!MainActivity.avail.Contains(device.Name + "\n" + device.Address))
{
MainActivity.avail.Add(device.Name + "\n" + device.Address);
ArrayAdapter arrayAdapter1 = new ArrayAdapter(context, Android.Resource.Layout.SimpleListItem1, MainActivity.avail);
MainActivity.dlist.Adapter = arrayAdapter1;
//address assigned a value
MainActivity.address = device.Address; MainActivity.name = device.Name;
MainActivity.mydevice = device;
}
}
Toast.MakeText(context, "Received the intent", ToastLength.Short).Show();
}
The remote device is not receiving this communication and i don't know why, Thank You

Check you have BLUETOOTH_ADMIN permission in Manifest. Register for ACTION_BOND_STATE_CHANGED intents to be notified when the bonding process completes, and its result. Get the result of device.CreateBond(), it returns false on immediate error, true if bonding will begin.
https://developer.android.com/reference/android/bluetooth/BluetoothDevice#createBond()

Related

BluetoothManager getConenctedDevices returns an empty array

I've connected to Xiaomi air buds via bluetooth settings on my phone.
Then, I tried to use getConnectedDevices(BluetoothProfile.GATT_SERVER) and getConnectedDevices(BluetoothProfile.GATT) methods to get a list of connected devices, but in both cases I got an empty array as a result. If I try to use some other profile in getConnectedDevices() I get an exception that says that I'm using a wrong profile.
How can I correctly get a list of currently connected bluetooth devices to my phone.
code example, in onCreate:
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
List<BluetoothDevice> connectedDevices = mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT_SERVER);
for (BluetoothDevice b :
connectedDevices) {
Log.e(TAG, "onStart: connectedDevice - " + b.toString() );
}
To get a list devices that you connected to ( in the past )
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedList = btAdapter.getBondedDevices();
for (BluetoothDevice pairedDevice : pairedList )
{
Log.d("BT", "pairedDevice.getName(): " + pairedDevice.getName());
Log.d("BT", "pairedDevice.getAddress(): " + pairedDevice.getAddress());
}
To get the device you correctly connected to you will have to use a broadcast receiver like in the following
private final BroadcastReceiver btReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i("Device",device.getName()+ "\n"+ device.getAddress()+"\n"+ device.getBondState());
}
}
};
There's a few more ways to just find out what the state of the connection of the headset as shown here.
if that still not answering your question then I'm sorry I probably misunderstood your question / need.

Android Bluetooth: fetchUuidsWithSdp() does not return all UUIDs on some devices

I have two different bluetooth apps. The first provides a service and listens to commands from the other commander app. I have a GT-I9100T phone and a GT-P5210 tablet. The tablet when acting at the listener works fine and the phone can see the UUID for my app. But when I run the phone as the listener, the UUID of the listener is not listed.
I filter the devices by my application UUID so that I know I am talking only to those devices with my application running.
My listening app looks like this (I get the same result if I use an insecure connection as well):
private final UUID GUID = UUID.fromString("3DEF793A-FA94-4478-AE56-108854B1EF4B");
// other stuff....
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(APP_NAME, GUID);
My commander app MainActivity looks likes this:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Log.i(TAG,"Action received: "+action);
if(action.equals(BluetoothDevice.ACTION_UUID)) {
BluetoothDevice btd = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i(TAG,"Received uuids for "+btd.getName());
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
StringBuilder sb = new StringBuilder();
List<String> uuids = new ArrayList<String>(uuidExtra.length);
if(uuidExtra != null) {
for (int i = 0; i < uuidExtra.length; i++) {
sb.append(uuidExtra[i].toString()).append(',');
uuids.add(uuidExtra[i].toString());
}
}
Log.i(TAG,"ACTION_UUID received for "+btd.getName()+" uuids: "+sb.toString());
ListContent.addItemWithUUIDs(btd, uuids);
}
}
}
My list content (I am using the master/detail template):
public static synchronized void addItem(BluetoothItem item) {
BluetoothDevice btd = item.mBluetoothDevice;
Log.i(TAG,"Attempting to add "+item.mBluetoothDevice.getName());
if(ITEMS.contains(item)) {
Log.i(TAG,item.mBluetoothDevice.getName()+" already in list");
return;
}
// Do we know this device?
Parcelable[] uuids = btd.getUuids();
Set<String> setUUIDs = new HashSet<String>();
StringBuilder sb = new StringBuilder();
if(uuids != null) {
for (Parcelable parcelable : uuids) {
sb.append(parcelable.toString()).append(',');
setUUIDs.add(parcelable.toString());
}
}
Log.v(TAG,"Device has uuids: "+sb.toString());
if ((btd.getUuids() != null && setUUIDs.contains(BluetoothItem.GUID.toLowerCase()))){
Log.i(TAG, "Found app device: " + btd.getName());
addItem(btd);
} else {
// If we don't know this device, perform sdp fetch of uuids
Log.i(TAG,"Requesting fresh UUIDs for: "+btd.getName());
// this is flushed when discovering finishes
CANDIDATES.add(btd);
}
}
public static synchronized void addItemWithUUIDs(BluetoothDevice btd, List<String> uuids) {
Log.i(TAG,"Attempting to add with uuids"+btd.getName()+" uuids: "+btd.getUuids());
if (uuids.contains(BluetoothItem.GUID)) {
Log.i(TAG, "Found app device: " + btd.getName());
addItem(btd);
} else {
Log.i(TAG, "Ignoring device " + btd.getName() + " without app guid");
}
}
When discovery is finished, this happens:
for (BluetoothDevice i : ListContent.CANDIDATES) {
Log.i(TAG,"Fetching UUIDs for "+i.getName());
i.fetchUuidsWithSdp();
}
ListContent.CANDIDATES.clear();
The logcat output when using the tablet as the commander and phone as listener:
DeviceListActivity(29524): Received uuids for GT-I9100T
DeviceListActivity(29524): ACTION_UUID received for GT-I9100T uuids:
0000110a-0000-1000-8000-00805f9b34fb,
00001105-0000-1000-8000-00805f9b34fb,
00001116-0000-1000-8000-00805f9b34fb,
0000112d-0000-1000-8000-00805f9b34fb,
0000112f-0000-1000-8000-00805f9b34fb,
00001112-0000-1000-8000-00805f9b34fb,
0000111f-0000-1000-8000-00805f9b34fb,
00001132-0000-1000-8000-00805f9b34fb,
I get the correct output with phone as commander and tablet as listener:
DeviceListActivity(23121): Received uuids for GT-P5210
DeviceListActivity(23121): ACTION_UUID received for GT-P5210 uuids:
00001105-0000-1000-8000-00805f9b34fb,
0000110a-0000-1000-8000-00805f9b34fb,
0000110c-0000-1000-8000-00805f9b34fb,
00001112-0000-1000-8000-00805f9b34fb,
00001115-0000-1000-8000-00805f9b34fb,
0000111f-0000-1000-8000-00805f9b34fb,
00001200-0000-1000-8000-00805f9b34fb,
3def793a-fa94-4478-ae56-108854b1ef4b,
As you can see, the GUID for my app is listed as the last item. I've tried making the devices discoverable and bonding and unbonding, but the GUID for my app is never returned for the phone. I have other non-Android devices that also use this GUID and they are discovered normally as well.
The phone is running 4.1.2 and the tablet is 4.2.2

Clear the bluetooth name cache in android

I want to clear the blueooth cache.
I'm making application about bluetooth.
I just knowed Android bluetooth device name is cached in the phone. (when phone find the bluetooth device)
I can't find solution anywhere.
I just saw fetchUuidsWithSdp().
someone said it clears the bluetooth cache in android phone.
but I don't know how use this method and I don't think that fetchUuidsWithSdp() will clear the cache.
Please Let me know how to clear the bluetooth cache in Android or how to use fetchUuidsWithSdp().
Thanks:)
Follow the instructions of the Android Guide in order to start the discovery.
When declaring your IntentFilter, add (at least) ACTION_FOUND and ACTION_UUID :
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_UUID);
Inside your receiver call fetchUuidsWithSdp().
You will get the UUIDs inside the ACTION_UUID:
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// get fresh uuids
device.fetchUuidsWithSdp();
}
else if (BluetoothDevice.ACTION_UUID.equals(action)) {
// Get the device and teh uuids
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
if(uuidExtra !=null){
for (Parcelable uuid : uuidExtra) {
Log.d("YOUR_TAG", "Device: " + device.getName() + " ( "+ device.getAddress() +" ) - Service: " + uuid.toString());
}
}
}

Get listed bluetooth devices uuid with out pairing

I can list out bluetoothdevices available, but I am not getting the server bluetoothdevice's UUID.
my purpose is to list out number of bluetooth server (another android device/s) available. I am not even sure how can I recognize my server device/s from all the bluetoothdevices available.
For the first mensioned issue, I used fetchUuidsWithSdp() also, but I am getting nullvalue in the UUID broadcast receiver. Somebody please help,
Thanks in advance.
bluetooth = BluetoothAdapter.getDefaultAdapter();
if(bluetooth != null)
{
String status;
if (bluetooth.isEnabled()) {
String mydeviceaddress = bluetooth.getAddress();
String mydevicename = bluetooth.getName();
status = mydevicename + " : " + mydeviceaddress;
bluetooth.startDiscovery();
}
else
{
status = "Bluetooth is not Enabled.";
}
}
And in Broadcast Receiver
public class Receiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction()))
{
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String uuid = intent.getStringExtra(BluetoothDevice.EXTRA);
}
}

How do you retrieve the WiFi Direct MAC address?

I am trying to retrieve the MAC address of an Android device. This is ordinarily possible through the WiFiManager API if WiFi is on.
Is there any way to get the MAC address if WiFi is off and WiFi Direct is on?
WiFi AND WiFi Direct can't be on at same time on my phone.
Thanks
I had been searching for this during my project. My requirements were to uniquely identify devices in an adhoc P2p network formed with WiFi Direct. Each device should identify its friend device the next time when it comes into proximity. I needed my own WiFi (Direct) MAC and my friends' to create a Key for this friend zone creation.
My Research: The design is in such a way that there is an Unique Universal ID and a Local ID. Reason: Universal ID can only be used to connect to Infrastructure mode Networks. Local ID could be used for "ad-hoc" mode networks(device to device). In this ad-hoc mode, there are possibilities that a single device might simultaneosly belong to several ad-hoc groups.
Hence to support this concurrent operations, P2p devices support
Multiple MAC entities, possibly on different channels.
For each session, a persistent group MAY use a different channel and device
MAC for each session.
P2P devices use their global MAC address as Device ID during discovery and negotiation, and a temporary local MAC address for all frames within a group. Understood from here
However, there is NO straight forward way to obtain one's own WiFi P2p MAC address. Issue 53437: Android.
In this issue discussion, the project member from google has suggested this is possible and just that it hasn't been documented
Solution: Using intent filter WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION and the extra
from the intent WifiP2pManager.EXTRA_WIFI_P2P_DEVICE
This is how I have used it in my project:
#Override
public void onReceive(Context context, Intent intent) {
....
....
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION
.equals(action)) {
WifiP2pDevice device = (WifiP2pDevice) intent
.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
String myMac = device.deviceAddress;
Log.d(TAG, "Device WiFi P2p MAC Address: " + myMac);
/* Saving WiFi P2p MAC in SharedPref */
sharedPref = context.getSharedPreferences(context.getString(R.string.sp_file_name), Context.MODE_PRIVATE);
String MY_MAC_ADDRESS = sharedPref.getString(context.getString(R.string.sp_field_my_mac), null);
if (MY_MAC_ADDRESS == null || MY_MAC_ADDRESS != myMac) {
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(context.getString(R.string.sp_field_my_mac), myMac);
editor.commit();
}
Hope this helps someone!
The mac addresss of WiFi is different than that of WiFi Direct. Usually first 2 letters might be different. Be careful about that.
The mac address of WiFi is different than that of WiFi Direct.
You can get WiFi direct address using next code:
public String getWFDMacAddress(){
try {
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface ntwInterface : interfaces) {
if (ntwInterface.getName().equalsIgnoreCase("p2p0")) {
byte[] byteMac = ntwInterface.getHardwareAddress();
if (byteMac==null){
return null;
}
StringBuilder strBuilder = new StringBuilder();
for (int i=0; i<byteMac.length; i++) {
strBuilder.append(String.format("%02X:", byteMac[i]));
}
if (strBuilder.length()>0){
strBuilder.deleteCharAt(strBuilder.length()-1);
}
return strBuilder.toString();
}
}
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
return null;
}
The WiFi Direct mac address is going to be different. It's explained beautifully by #auselen here https://stackoverflow.com/a/14480530/3167704.
I just figured out a way to retrieve WiFi Direct mac address. It isn't pretty but gets the job done. Here's the code,
final WifiP2pManager p2pManager = (WifiP2pManager) getSystemService(WIFI_P2P_SERVICE);
final WifiP2pManager.Channel channel = p2pManager.initialize(this, getMainLooper(), null);
p2pManager.createGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
p2pManager.requestGroupInfo(channel, new WifiP2pManager.GroupInfoListener() {
#Override
public void onGroupInfoAvailable(WifiP2pGroup wifiP2pGroup) {
Log.i("", wifiP2pGroup.getOwner().deviceAddress);
// Following removal necessary to not have the manager busy for other stuff, subsequently
p2pManager.removeGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.i("", "Removed");
}
#Override
public void onFailure(int i) {
Log.i("", "Failed " + i);
}
});
}
});
}
#Override
public void onFailure(int i) {
Log.i("", String.valueOf(i));
}
});

Categories

Resources