Android 6.0上的蓝牙低功耗startScan找不到设备

Jac*_*osi 46 android bluetooth bluetooth-lowenergy android-6.0-marshmallow

我正在使用Nexus 5开发一个使用蓝牙低功耗的应用程序.它在Lollipop上工作,现在它不能用于Marshmallow.我在清单和活动中的runTime上设置了ACCESS_COARSE_LOCATION和ACCESS_FINE_LOCATION权限.

这是ScanFilters列表:

mScanFilterTest = new ScanFilter.Builder().build();
mScanFilter = new ArrayList<ScanFilter>();
mScanFilter.add(mScanFilterTest);
Run Code Online (Sandbox Code Playgroud)

这些是设置:

mScanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_POWER).setReportDelay(0)
                .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).build();
Run Code Online (Sandbox Code Playgroud)

这些是我的回调:

 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, "------------------------------------------");
         }
     };
Run Code Online (Sandbox Code Playgroud)

这是我的电话:

mBluetoothLeScanner.startScan(mScanFilter, mScanSettings, mBLEScan);
Run Code Online (Sandbox Code Playgroud)

它开始扫描但没有找到任何设备.请帮我!!!!

V-P*_*PTR 64

我在同样的问题上挣扎.要解决此问题,您必须在手机设置中启用"位置"(GPS),在运行时请求应用程序中的位置权限.两者都需要完成扫描才能正常工作.

要请求位置权限,请将以下内容放入对话框或类似内容中:

yourActivity.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, yourPermissionRequestCode);
Run Code Online (Sandbox Code Playgroud)

并实施:

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

in yourActivity和处理用户选择的任何内容.您还需要执行以下操作才能打开设备的位置服务:

Intent enableLocationIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
yourActivity.startActivityForResult(enableLocationIntent, yourServiceRequestCode);
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式检查用户是否打开了位置服务:

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

yourActivity.您还可以通过执行以下操作手动打开位置(GPS)服务:

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

它应该在手机设置中如下所示:

在电话设置中启用位置(GPS)服务

或者在快速设置下拉菜单中这样:

下拉设置中启用位置(GPS)服务

用户启用权限并启动位置服务后,您应该开始扫描.我注意到,如果您在启用权限/启用位置服务时已经扫描,它仍然不会在您的内容中放置任何内容onScanResults

我不确定这是否是iBeacons /蓝牙广告的错误或"功能"(注意:广告与销售产品而非技术蓝牙广告一样),以便公司可以查看您的位置并将您引导到他们想要的位置.

希望这可以解决您的问题!

编辑 我想添加:你只需要这个扫描.连接到BLE设备后,您可以关闭手机上的位置服务,但仍然可以连接到您的设备.但是,您无法发现或连接到任何新设备,并且所有广告设备都将从中删除onScanResults

  • @Matt Wolfe是的,我同意,这似乎是一个巨大的错误.事实上,已发布错误报告[此处](https://code.google.com/p/android/issues/detail?id=189090&q=ble%20android%206.0&colspec=ID%20Type%20Status%20Owner% 20Summary%20Stars)询问它是怎么回事.我对这种方式的假设是,它允许广告公司使用仅BLE GAP的广告设备(iBeacon设备等)来查找客户在物理上位于零售店的位置(使用三角测量)并能够指导他们到商店里的其他地方的产品.但我可能完全错了. (6认同)
  • 这有效,但它似乎是android系统中的一个巨大的bug.为什么扫描需要GPS?我的应用程序使用GPS但仅适用于希望启用该功能的客户,因此对于在我们的应用程序中禁用该功能的客户而言,如果我们可以扫描BLE设备,则会提示您打开GPS,这会让您感到困惑. (4认同)
  • @ V-PTR*它似乎是一个巨大的错误* - 我读了问题跟踪器,但我认为它不是一个错误.这是Google打算保护用户的一项功能.现在,由于IoT,蓝牙设备的MAC地址可以用于位置识别.我猜Google的架构师认为,当用户可能存在隐私风险时,应始终注意这些用户.我认为预先Marshmallow设备在处理蓝牙设备信息方面存在隐私保护问题. (4认同)
  • 我实际上只打开GPS,一切都工作,没有使用requestPermissions().我假设在添加requestPermissions()之后扫描可以在没有打开GPS的情况下工作,但我错了.谷歌到底怎么了?! (3认同)
  • @MrColes 我不认为它必须是 GPS。我认为只要定位服务开启,任何一个都可以工作。我之所以将其命名为 GPS,是因为我个人将定位服务与 GPS 联系在一起。我还没有明确尝试过不同的位置模式,但我认为这不会有什么不同。 (2认同)