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

Posted

技术标签:

【中文标题】Android 6.0 上的低功耗蓝牙 startScan 找不到设备【英文标题】:Bluetooth Low Energy startScan on Android 6.0 does not find devices 【发布时间】:2016-01-07 17:11:16 【问题描述】:

我正在使用 Nexus 5 开发具有低功耗蓝牙的应用程序。它在 Lollipop 上工作,现在在 Marshmallow 上不工作。 我在清单和 Activity 的运行时设置了 ACCESS_COARSE_LOCATION 和 ACCESS_FINE_LOCATION 权限。

这是扫描过滤器的列表:

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

这些是设置:

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

这些是我的回调:

 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, "------------------------------------------");
         
     ;

这是我的电话:

mBluetoothLeScanner.startScan(mScanFilter, mScanSettings, mBLEScan);

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

【问题讨论】:

【参考方案1】:

我在同样的问题上苦苦挣扎。要修复它,您必须在手机的设置中启用“位置”(GPS)以及在运行时在应用程序中请求位置权限。两者都需要完成才能使扫描正常工作。

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

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

并实施:

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

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

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

你可以通过实现来检查用户是否开启了定位服务:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)

    if(requestCode == yourServiceRequestCode)
    
        ...//Do whatever you need to
    

yourActivity。您还可以通过以下方式手动开启定位 (GPS) 服务:

Enter phone settings -&gt; Select "Location" -&gt; Then turn it on

在电话设置中应该如下所示:

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

一旦用户启用了权限并启动了定位服务,那么您应该开始扫描。我注意到,如果您在启用权限/打开定位服务时已经在扫描,它将仍然没有在你的onScanResults中放任何东西

我不确定这是否是 iBeacons/蓝牙广告的错误或“功能”(注意:广告作为销售产品而不是技术蓝牙广告)允许公司查看您的位置并将您定向到他们的位置想要。

希望这能解决您的问题!

编辑 我的意思是补充:你只需要这个来进行扫描。连接到 BLE 设备后,您可以关闭手机上的定位服务,您仍将连接到您的设备。但是,您将无法发现或连接到任何新设备,并且所有广告设备将从onScanResults 中删除

【讨论】:

这可行,但它似乎是 android 系统中的一个巨大错误。为什么必须使用 GPS 才能进行扫描?我的应用使用 GPS,但仅适用于希望启用该功能的客户,因此在我们的应用中禁用它的客户会因为收到提示打开 GPS 以扫描 BLE 设备而感到困惑。 @Matt Wolfe 是的,我同意,这似乎是一个巨大的错误。事实上,已经发布了一个错误报告 here 询问它发生了什么。关于为什么会这样,我的假设是它允许广告公司使用仅支持 BLE GAP 的广告设备(iBeacon 设备等)来查找客户在零售店的物理位置(使用三角测量)并能够指导他们到商店其他地方的产品。但我可能完全错了。 我实际上只打开了 GPS 并且没有使用 requestPermissions() 一切正常。我假设在添加 requestPermissions() 后扫描可以在没有打开 GPS 的情况下工作,但我错了。谷歌到底是什么?! @V-PTR 这似乎是一个巨大的错误 -- 我阅读了问题跟踪器,但我认为它不是错误。这是 Google 旨在保护用户的一项功能。现在,由于物联网,蓝牙设备的 MAC 地址可用于位置识别。我猜谷歌的架构师认为,当用户可能面临隐私风险时,他们应该始终受到关注。我认为 Marshmallow 之前的设备在处理蓝牙设备信息方面存在隐私保护问题。 @MrColes 我不认为它必须是 GPS。我认为只要位置服务开启,任何一个都可以工作。我简单地命名为 GPS,因为这是我个人将定位服务与它联系起来的。我没有明确尝试过不同的定位模式,但我认为应该不会有什么不同。【参考方案2】:

就像@Jacopo Tosi 所说,您必须请求位置权限。 你可以阅读here 怎么做。 而且您还必须打开位置。我不知道为什么这样做。但这是我设法让它发挥作用的唯一方法。

【讨论】:

我打开了位置,它开始扫描,但它没有在回调中回复任何内容 它并没有真正让它变得更好,但其背后的原因是 BLE 信标通常用作一种室内 GPS 来跟踪用户位置。因此,您必须与您的用户进行一次尴尬的对话才能请求许可并保证您不会尝试跟踪他们,尽管他们只是将该许可授予心率监测器。【参考方案3】:

在我的情况下(HTC M9),我还必须进入蓝牙下的 Android 设置菜单并手动扫描 BT 设备。

【讨论】:

以上是关于Android 6.0 上的低功耗蓝牙 startScan 找不到设备的主要内容,如果未能解决你的问题,请参考以下文章

推荐用于BMS锂电池管理系统的低功耗蓝牙芯片MS1656

原创Android 5.0 BLE低功耗蓝牙从设备应用

多功能的低功耗蓝牙可穿戴设备用于监测血液酒精浓度

Android 低功耗蓝牙开发 (扫描过滤自定义服务与特性)Kotlin版

Android 低功耗蓝牙开发 (扫描过滤自定义服务与特性)Kotlin版

nRF52系列来袭,Nordic的低功耗蓝牙方案大有可为