I've a simple service to pair bluetooth devices and it look like this:
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
if(!extras.containsKey("bluetoothAddress"))
return;
String bluetoothAddress = extras.getString("bluetoothAddress");
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if(!adapter.isEnabled()) {
adapter.enable();
}
BluetoothDevice device = adapter.getRemoteDevice(bluetoothAddress);
device.createBond();
}
It works perfectly fine except that sometimes the pair dialogue pop up and sometimes it show up in my notifications bar and I have to open it manually. Is there any way to make sure that it always pop up to the front?
I've tried to google on it and only thing I can find is that if you stay in bluetooth settings it always pop up, but that seems like a ugly solution. The reason for all of this is that I'm working with automation and want to make sure that when I run my service I get the pair dialogue can just click "Pair".
I had the same problem. I've found this post that explains when the dialog is shown or not: Bluetooth pairing request on notification bar?
Resuming, it depends on the result of the shouldShowDialogInForeground() method.
Quoting from the post:
... there are ways of making the dialog show:
If the device was in discoverable mode recently
If the device was discovering recently
If the device was picked in the device picker recently
If Bluetooth Settings is visible
In my case to force the dialog to appear, I started and canceled a discovery before trying to pair...
Code/Hack
BluetoothAdapter.getDefaultAdapter().startDiscovery();
//Give it some time before cancelling the discovery
Thread.sleep(1000);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
//Then do the LeScan and connect to the device
PS:I know it's a horrible hack but is the only way I got this to work, and the pairing must be done only once for device so it's not so terrible... Also, if anybody finds a better way I'm open to suggestions
I use following code to resolve the issue
if(!BluetoothAdapter.getDefaultAdapter().isDiscovering())
BluetoothAdapter.getDefaultAdapter().startDiscovery();
//make sure that the device is in discovering
while (!BluetoothAdapter.getDefaultAdapter().isDiscovering());
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
Related
I have a bluetooth device , I want to know how to obtain the method when connected Bluetooth device is out of range
like code
//if bluetooth is Not in the range of connection
{
}
Please give me some solution
To check whether a bluetooth device is connected or not you can use intent filters to listen to the ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECT_REQUESTED, and ACTION_ACL_DISCONNECTED broadcasts. For more details please check this post How to programmatically tell if a Bluetooth device is connected? (Android 2.2)
There is no internal method like DeviceNotInRange() {} hence you need to work it out by creating your customized method. You need to create a method that keep searching on a regular interval and when device is not in range, you can raise an Alert or sound for intimation.
Everywhere I look I find this method "getBondedDevices()" for my bluetooth adapter. However, I have my tablet and another bluetooth device sitting next to me, and I can't figure out how to actually get the device to show up on the list of bonded devices.
In Bluetooth terms, "bonded" and "paired" are basically synonyms (officially, the process of pairing leads to a bond, but most people use them interchangeable). In order for your device to be added to that list, you must go through the process of Discovery, which is how one device searches and finds another, and then Pair the two together.
You can actually do this from the device settings as a user, but if you are looking to so so within the context of an app, your process will likely look something like this:
Register a BroadcastReceiver for BluetoothDevice.ACTION_FOUND and BluetoothAdapter. ACTION_DISCOVERY_FINISHED
Start discovery by calling BluetoothAdapter.startDiscovery()
Your receiver will get called with the first action every time a new device is found in range, and you can inspect it to see if it's the one you want to connect with. You can call BluetoothAdapter.cancelDiscovery() once you've found it to not waste the battery any more than necessary.
When discovery is complete, if you haven't canceled it, your receiver will get called with the second action; so you know not to expect any more devices.
With a device instance in hand, open a BluetoothSocket and connect(). If the devices are not already bonded, this will initiate pairing and may show some system UI for a PIN code.
Once paired, your device will show up in the bonded devices list until the user goes into settings and removes it.
The connect() method also actually opens the socket link, and when it returns without throwing an exception the two devices are connected.
Now connected, you can call getInputStream() and getOutputStream() from the socket to read and write data.
Basically, you can inspect the list of bonded devices to quickly get access to an external device, but in most applications you will be doing a combination of this and true discovery to make sure you can always connect to the remote device regardless of what the user does. If a device is already bonded, you'd just be doing steps 5-7 to connect and communicate.
For more information and sample code, check out the "Discovering Devices" and "Connecting Devices" sections of the Android SDK Bluetooth Guide.
HTH
API level 19 and above you can call createBond() on BluetoothDevice instace to which you want to connect.
You will require some permissions to discover and list the visible devices
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Code to discover and list the devices:
bluetoothFilter.addAction(BluetoothDevice.ACTION_FOUND);
bluetoothFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
bluetoothFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(bluetoothReceiver, bluetoothFilter);
private BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
Log.e("bluetoothReceiver", "ACTION_FOUND");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devicesList.add((device.getName() != null ? device.getName() : device.getAddress()));
bluetoothDevicesAdapter.notifyDataSetChanged();
} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Log.e("bluetoothReceiver", "ACTION_DISCOVERY_STARTED");
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Log.e("bluetoothReceiver", "ACTION_DISCOVERY_FINISHED");
getActivity().unregisterReceiver(bluetoothReceiver);
}
}
};
Just call createBond() on selected device.
I am working on a project related to Bluetooth. I wrote this sample code to detect Bluetooth in a device.
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
if(bluetooth!=null)
{
Toast.makeText(getApplicationContext(), "gfvhfh", Toast.LENGTH_LONG).show();
}
This code is working perfectly in my phone and displaying the text in toast, but in my system it's not showing anything. I am using a external Bluetooth adapter for my system.
I guess that by system you mean emulator, in that case it is 100% normal.
You can't use Bluetooth on the emulator as said here.
Please check before asking a question that it hasn't been asked before!
I'm developing an Android app that has to exchange some data through BT by automatically create a communication between two devices. To do so the only way (I've found) is to first make the device find each other and then negotiate a master who will open a ServerSocket and host the connection.
My problem then is how to toggle BT discoverability without prompting the request to the user!
I've searched the net with no success, so I start thinking about possible solution.
First I thought about something like a BroadcastReceiver that would catch the request instead the default activity launched by StartActivity(new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE)), but then I wouldn't know what to do to actually make the device discoverable.
Recently I've thought about hiding or dismissing the dialog raised by the precedent call by automatically selecting the positive button. Once again I've no clue on how to do it!
Any help will be really appreciate, thank you in advance to everyone and sorry for my bad English!
I can't point to any explicit documentation, but I'm pretty sure you're not allowed to silently turn on and off Bluetooth in android. Bluetooth discoverability is something that at the end of the day is always up to the user. To subvert their authority presents a huge security concern.
You can call .enable() on an instance of BluetoothAdapter
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.enable();
I have an app where I am programmatically controlling Bluetooth pairing and unpairing. I can pair before connection and unpair afterwards. The reason I need to do this is specific to my application and not in the scope of my question.
Basically what I am doing is:
Get a reference ib to IBluetooth object as described in this answer
Register a BroadcastReceiver for android.bluetooth.device.action.PAIRING_REQUEST
Call ib.createBond(address)
Wait for BroadcastReceiver to trigger
Convert user pin into bytes with convertPinToBytes()
Call ib.setPin(address, pinBytes) from within BroadcastReceiver
Anyways, this approach works great, except for the fact that when I do the pairing, I get a notification in the Status bar requesting that the user enter a PIN to complete the pairing. But this is in fact unnecessary, because by the time the user sees this, my app has already used setPin(). I'd really like for that notification to either a) not appear at all, or b) be dismissed automatically somehow.
I realize this may not even be possible, but I thought I would ask in case someone has a creative idea.
Try setting the confirmation first in the PAIRING_REQUEST
BluetoothDevice device = intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
device.getClass().getMethod("cancelPairingUserInput").invoke(device);
This worked for me between two Android devices using RFCOMM but I'm not entering any PINs
Since Android API 19 Google switched these Methods to public Methods, so there is no need for Reflection any more. :)
Do this in the PAIRING_REQUEST notification event:
BluetoothDevice localBluetoothDevice = (BluetoothDevice)intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
Class localClass = localBluetoothDevice.getClass();
Class[] arrayOfClass = new Class[0];
localClass.getMethod("cancelPairingUserInput", arrayOfClass).invoke(paramBluetoothDevice, null)).booleanValue();
But you gotta tell me how did you pair your remote device without the user to enter Passkey/PIN? off course, you know the PIN for the remote device which is trying to pair to your device but how did you provide that PIN to the remote device.