I'm currently working on a little app to get started with the services that the Bluetooth Android API can provide.
Edit -> Answer:
It seems that the issue was due to the specific Nexus 5 devices. Seems like their bluetooth receiver doesn't work well. Solution below should work for other devices
Remark:
I’ve read the documentation here: http://developer.android.com/guide/topics/connectivity/bluetooth.html as well as the following source code of this tutorial http://www.londatiga.net/it/programming/android/how-to-programmatically-scan-or-discover-android-bluetooth-device/ located on github under /lorensiuswlt/AndroBluetooth
I’ve finished almost all the features that interested me (such as check for adapter existence, enable/disable the blueooth, querying paired divices, set the adapter discoverable).
Issue:
Actually no device is found when i launch the .onDiscovery() method, even though devices are found from Settings/Bluetooth on my Nexus 5.
Here is how I handle it:
public class MainActivity extends AppCompatActivity { private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); ... protected void onCreate(Bundle savedInstanceState) { IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_FOUND); filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); registerReceiver(mReceiver, filter); }
The filter is working well as far as i could try, i.e ACTION_STATE_CHANGED (on bluetooth enabling) and the two ACTION_DISCOVERY_***.
The following method is then successfuly called:
public void onDiscovery(View view) { mBluetoothAdapter.startDiscovery(); }
And then i have my bluetooth receiver:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); if (state == BluetoothAdapter.STATE_ON) { showToast("ACTION_STATE_CHANGED: STATE_ON"); } } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) { mDeviceList = new ArrayList<>(); showToast("ACTION_DISCOVERY_STARTED"); mProgressDlg.show(); } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action) && !bluetoothSwitchedOFF) { mProgressDlg.dismiss(); showToast("ACTION_DISCOVERY_FINISHED"); Intent newIntent = new Intent(MainActivity.this, DeviceListActivity.class); newIntent.putParcelableArrayListExtra("device.list", mDeviceList); startActivity(newIntent); } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {// When discovery finds a device // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); mDeviceList.add(device); showToast("Device found = " + device.getName()); } } };
I don't have any issue coming out the logcat and didn't notice any trouble during the test I did. The only problem is that no device is discovered at the end of the scan, when many discoverable ones are available arround.
I tried to not put too much code in order to not flood the topic. Ask me if you need more.
Thanks for reading me, and thanks in advance for you answers.
It's usually because the device's own Bluetooth is switched off, or isn't in pairing mode. Check the user manual to find out how to make it discoverable by turning on pairing mode. With some headphones, it's a case of holding the power button down for longer, but with other devices there's a dedicated Bluetooth button.
If your Bluetooth devices won't connect, it's likely because the devices are out of range, or aren't in pairing mode. If you're having persistent Bluetooth connection problems, try resetting your devices, or having your phone or tablet "forget" the connection.
Using this property of Bluetooth, an app called Wunderfind for iPhone or Android can help you physically locate a lost, hidden, or unknown Bluetooth device using your smartphone. This includes PCs, laptops, tablets, smartphones, Bluetooth headphones, Airpods, smartwatches, smart home devices, and more.
What version of Android are you running this on? If it is Android 6.x, I believe you need to add the ACCESS_FINE_LOCATION
permission to your manifest. For example:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
I had a similar issue and this fixed it for me.
UPDATE: Adding documentation direct from Google on this:
To access the hardware identifiers of nearby external devices via Bluetooth and Wi-Fi scans, your app must now have the
ACCESS_FINE_LOCATION
orACCESS_COARSE_LOCATION
permissions
UPDATE 2020: We recently updated our application to target SDK Version 29. In doing this, our application stopped being able to discover Bluetooth devices again. We have been using ACCESS_COARSE_LOCATION
since this answer was originally written. Changing to ACCESS_FINE_LOCATION
appears to fix the issue. I now recommend developers try ACCESS_FINE_LOCATION
if targeting 29+. Answer updated to reflect this.
Bit late to the party but this may come in handy for other people.
You need to do two things
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
or <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
to your AndroidManifest.xml
Make sure you're requesting the permission on runtime as well for Android 6.0 Devices by using something like this
int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1; ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
just before mBluetoothAdapter.startDiscovery();
If you don't do step 2 you won't be able to get any Hardware Identifier info on device with Android >= 6.0
UPDATE/EDIT:
Example with Android Version check and alert dialog as warning
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // Only ask for these permissions on runtime when running Android 6.0 or higher switch (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION)) { case PackageManager.PERMISSION_DENIED: ((TextView) new AlertDialog.Builder(this) .setTitle("Runtime Permissions up ahead") .setMessage(Html.fromHtml("<p>To find nearby bluetooth devices please click \"Allow\" on the runtime permissions popup.</p>" + "<p>For more info see <a href=\"http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id\">here</a>.</p>")) .setNeutralButton("Okay", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(DeviceListActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_ACCESS_COARSE_LOCATION); } } }) .show() .findViewById(android.R.id.message)) .setMovementMethod(LinkMovementMethod.getInstance()); // Make the link clickable. Needs to be called after show(), in order to generate hyperlinks break; case PackageManager.PERMISSION_GRANTED: break; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With