Bluetooth Low Energy startScan on Android 6.0 does not find devices

44,766

Solution 1

I struggled with the same issue. To fix it you have to enable "Location" (GPS) in the settings of the phone as well as request location permission in the app at runtime. Both need to be done for scanning to work properly.

To request the location permission put the following in a dialog or the likes:

yourActivity.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, yourPermissionRequestCode);

and implement:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults){
    if(requestCode == yourPermissionRequestCode)
    {
        ... //Do something based on grantResults
    }
}

in yourActivity and handle whatever the user selects. You also need to do the following to turn on your device's location services:

Intent enableLocationIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
yourActivity.startActivityForResult(enableLocationIntent, yourServiceRequestCode);

You can check if the user turned on the location services by implementing:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if(requestCode == yourServiceRequestCode)
    {
        ...//Do whatever you need to
    }
}

in yourActivity. You can also manually turn on location (GPS) services by doing:

Enter phone settings -> Select "Location" -> Then turn it on

It should look like this in the Phone settings:

Location (GPS) services enabled in Phone Settings

Or like this in the quick-settings drop down:

Location (GPS) services enabled in drop down settings

Once the user has enabled the permission and started location services then you should start scanning. I've noticed that if you are already scanning while you enable the permission/turn on the location service it will still not put anything in your onScanResults

I'm not sure if this is a bug or a "feature" for iBeacons/Bluetooth advertising (NOTE: advertising as in selling products not the technical Bluetooth advertising) to allow companies to see your location and direct you to where they want.

Hope this fixes your problem!

EDIT I meant to add: you only need this for SCANNING. Once you are connected to the BLE device you can shut off the location service on your phone and you will still be connected to your devices. However, you cannot then discover or connect to any new devices and all advertising devices will drop from the onScanResults

Solution 2

Like @Jacopo Tosi say you must ask for location permissions. You can read here how to do it. And you also must turn on Location. i don't know why the did it. but it's the only way i managed to make it work.

Share:
44,766

Related videos on Youtube

Jacopo Tosi
Author by

Jacopo Tosi

Updated on November 20, 2020

Comments

  • Jacopo Tosi
    Jacopo Tosi over 3 years

    I'm developing an application with Bluetooth Low Energy using Nexus 5. It worked on Lollipop and now it is not working on Marshmallow. I set the ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION permissions in the manifest and on runTime in the Activity.

    This is the list of ScanFilters:

    mScanFilterTest = new ScanFilter.Builder().build();
    mScanFilter = new ArrayList<ScanFilter>();
    mScanFilter.add(mScanFilterTest);
    

    These are the settings:

    mScanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_POWER).setReportDelay(0)
                    .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).build();
    

    These are my callbacks:

     mBLEScan = new ScanCallback() {
         @Override
         public void onScanResult(int callbackType, ScanResult result) {
             super.onScanResult(callbackType, result);
             Log.i(TAG, "******************************************");
             Log.i(TAG, "The scan result " + result);
             Log.i(TAG, "------------------------------------------");
             }
         };
    

    This is my call:

    mBluetoothLeScanner.startScan(mScanFilter, mScanSettings, mBLEScan);
    

    It starts the scan but does not find any device. Please help me!!!!

  • Jacopo Tosi
    Jacopo Tosi over 8 years
    I did it throught the settings and also with the code but it does not work. I add the permissions in the Manifest and also in the Activity at runTime. My manifest is: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  • Jacopo Tosi
    Jacopo Tosi over 8 years
    I turned on the location, it starts scanning but it doesn't reply anything in the callback
  • V-PTR
    V-PTR over 8 years
    Sorry for the delay, I updated my answer to be more complete. The big thing is you need to request the ACCESS_COURSE_LOCATION permission at run time AND turn on location services for the device. Once those are done you should start your scan and it should return something. Please let me know if this worked
  • Jacopo Tosi
    Jacopo Tosi over 8 years
    I solved right now, the problem was you must turn on the gps during the scan. I don't know if you would say the same but this is the solution I found and it is working now.
  • V-PTR
    V-PTR over 8 years
    Yeah, sorry for the confusion. The Location services I mention in the answer is the same as the GPS setting you mention. Sorry about that!
  • Matt Wolfe
    Matt Wolfe over 8 years
    This works but it seems like a huge bug in the android system. Why must GPS be required in order to scan? My app uses GPS but only for customers who want that feature enabled and thus it will be confusing for customers who have it disabled in our app to get prompted to turn on GPS just so we can scan for BLE devices.
  • V-PTR
    V-PTR over 8 years
    @Matt Wolfe Yes, I agree, it seems like a huge bug. In fact, a bug report has been posted here asking what is going on with it. My hypothesis as to why it is this way is it allows advertising companies to use BLE GAP-only advertising devices (iBeacon devices and the like) to find where a customer is physically located a retail store (using triangulation) and be able to direct them to a product somewhere else in the store. But I could be completely wrong.
  • Lo-Tan
    Lo-Tan over 8 years
    I actually only turned on GPS and everything worked without using requestPermissions(). I assumed after adding requestPermissions() the scan would work without GPS turned on, but I was wrong. What the hell Google?!
  • Brian Reinhold
    Brian Reinhold over 8 years
    Minor typo: COURSE needs to be COARSE
  • V-PTR
    V-PTR over 8 years
    @BrianReinhold Thank you, it should be fixed now
  • hata
    hata about 8 years
    @V-PTR it seems like a huge bug -- I read the Issue Tracker, but I concluded it not a bug. It is a feature which Google intends to for protecting users. Now, because of IoT, MAC addresses of bluetooth devices may be used for location identification. I guess architects of Google thought users should be noticed always when they are potentially in privacy risk. I think rather pre-Marshmallow devices have privacy protection problem about handling bluetooth devices information.
  • caller9
    caller9 almost 8 years
    It doesn't really make it any better, but the reason behind it is that BLE beacons are often used as a sort of indoor GPS to track user location. So you have to have an awkward conversation with your user to request the permission and promise you will not try to track them, though they just granted that permission to a heart-rate monitor.
  • Linard Arquint
    Linard Arquint over 7 years
    thank you very much! location was not turned off in the quick-settings - wtf, already asking for location permission is confusing for the end user, but turning location on is even for me as developer extremely strange. I even didn't got an error message
  • MrColes
    MrColes over 7 years
    @V-PTR you explicitly call out GPS, but I don’t see how GPS is specifically picked vs other location options, e.g., I see “GPS, Wi-Fi, and mobile networks”, “Wi-Fi and mobile networks”, and “GPS only”—should all work or only some? And if some, then is there anything special in making sure one of those is requested/set?
  • V-PTR
    V-PTR over 7 years
    @MrColes I don't believe it has to be GPS. I think any will work as long as the location service is on. I simply named GPS because that's what I personally associate location services with. I haven't explicitly tried the different location modes but I don't think it should make a difference.
  • MrColes
    MrColes over 7 years
    @V-PTR one other nuance—in my testing, I see that Android 6.x only requires the permission, while Android 7.x requires both the permission and for location to be set to “on”. Do you or anyone else know if this is either a difference between 6.x & 7.x or a coincidence and maybe just different manufacturer’s phones being different?
  • Billyjoker
    Billyjoker almost 7 years
    I've got scan devices but not shows me the same devices as if i go to Settings -> Bluetooth -> scan, i'm missing bluetooth devices
  • hasbi
    hasbi about 6 years
    To be clear, getting permission for location is not enough anymore? we need to force user to switch on location to scan BLE devices? am I wrong?