Android 蓝牙LE扫描有时不';找不到设备

Android 蓝牙LE扫描有时不';找不到设备,android,bluetooth,bluetooth-lowenergy,android-bluetooth,Android,Bluetooth,Bluetooth Lowenergy,Android Bluetooth,我正在扫描蓝牙LE设备并作为外设运行(在Moto G第二代上运行Android 6.0) 我遇到的问题是,有时(看起来是随机的,但经常)它找不到我的任何其他外围设备,其他时候它工作正常 我有一个运行类似代码的iOS配套设备(扫描外设和充当外设),当安卓扫描找不到iOS设备时,我的iOS会发现安卓设备充当外设很好。所以这似乎只是扫描方面的问题 它不仅找不到我的iOS设备,而且找不到任何蓝牙设备。当它工作时,它会找到我的iOS设备以及一堆其他设备 我试过使用扫描过滤器和不使用扫描过滤器,都遇到了同样

我正在扫描蓝牙LE设备并作为外设运行(在Moto G第二代上运行Android 6.0)

我遇到的问题是,有时(看起来是随机的,但经常)它找不到我的任何其他外围设备,其他时候它工作正常

我有一个运行类似代码的iOS配套设备(扫描外设和充当外设),当安卓扫描找不到iOS设备时,我的iOS会发现安卓设备充当外设很好。所以这似乎只是扫描方面的问题

它不仅找不到我的iOS设备,而且找不到任何蓝牙设备。当它工作时,它会找到我的iOS设备以及一堆其他设备

我试过使用扫描过滤器和不使用扫描过滤器,都遇到了同样的问题。 我是根据SDK 26构建的,最小SDK为23

我正在设置所需的权限,因为它有时会起作用

相关代码如下:

private void startScanning() {
    mHandler = new Handler(mContext.getMainLooper());

    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            ScanSettings settings = new ScanSettings.Builder()
                                        .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                                        .setReportDelay(0)
                                        .build();

            mBluetoothLeScanner.startScan(null, settings, mScanCallback);
        }
    }, 1000);
}

private ScanCallback mScanCallback = new ScanCallback() {
    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        super.onScanResult(callbackType, result);

        if( result == null || result.getDevice() == null )
            return;

        Log.e("myTest", "Found Device");

        BluetoothDevice device = result.getDevice();
        final String deviceAddress = device.getAddress();

        List<ParcelUuid> parcel = result.getScanRecord().getServiceUuids();

        if (parcel != null) {
            String parcelUUID = parcel.toString().substring(1,37);

            if (parcelUUID.equalsIgnoreCase(mContext.getString(R.string.service_uuid))) {
                final BluetoothDevice bleDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(deviceAddress);

                if (!seenPeripherals.contains(deviceAddress)) {
                    stopScanning();

                    mHandler = new Handler(mContext.getMainLooper());

                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            Log.e("AppToApp", "Trying to connect to device " + deviceAddress);

                            mGatt = bleDevice.connectGatt(mContext, false, mGattCallback);
                        }
                    }, 1000);
                }
            }
        }   
    }
}
private void startScanning(){
mHandler=新处理程序(mContext.getMainLooper());
mHandler.postDelayed(新的Runnable(){
@凌驾
公开募捐{
ScanSettings=new ScanSettings.Builder()
.setScanMode(扫描设置.SCAN\u模式\u低延迟)
.setReportDelay(0)
.build();
mBluetoothLeScanner.startScan(空、设置、mScanCallback);
}
}, 1000);
}
private ScanCallback mScanCallback=新建ScanCallback(){
@凌驾
公共void onScanResult(int callbackType、ScanResult){
super.onScanResult(回调类型、结果);
if(result==null | | result.getDevice()==null)
返回;
Log.e(“我的测试”,“发现的设备”);
BluetoothDevice=result.getDevice();
最后一个字符串deviceAddress=device.getAddress();
List parcel=result.getScanRecord().getServiceUuids();
如果(包裹!=null){
字符串PARCELUID=parcel.toString().substring(1,37);
if(parcelouid.equalsIgnoreCase(mContext.getString(R.string.service_uuid))){
最终BluetoothDevice bleDevice=BluetoothAdapter.getDefaultAdapter().getRemoteDevice(deviceAddress);
如果(!seenPeripherals.contains(deviceAddress)){
停止扫描();
mHandler=新处理程序(mContext.getMainLooper());
mHandler.postDelayed(新的Runnable(){
@凌驾
公开募捐{
Log.e(“AppToApp”、“尝试连接到设备”+设备地址);
mGatt=bleDevice.connectGatt(mContext,false,mGattCallback);
}
}, 1000);
}
}
}   
}
}

我面临同样的问题。这是因为谷歌对棉花糖API 23及更高版本的政策已经更改,要使用BLE,用户需要在GPS上打开。对于谷歌文档,请查看此链接。要修复此问题,您必须在手机设置中启用“位置”,并在运行时在应用程序中请求位置权限。为了使扫描正常工作,这两项工作都需要完成

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

myActivity.requestPermissions(new String[]{Manifest.permission.ACCESS_COURSE_LOCATION}, yourPermissionRequestCode);
并实施:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] Results){
    if(requestCode == yourPermissionRequestCode)
    {
        ... //Do something based on Results
    }
}
myActivity
中,处理用户选择的任何内容。您还需要执行以下操作才能打开设备的位置服务:

Intent enableLocationIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
myActivity.startActivityForResult(enableLocationIntent, yourServiceRequestCode);
您可以通过执行以下操作来检查用户是否打开了位置服务:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if(requestCode == yourServiceRequestCode)
    {
        ...//Do whatever you need to
    }
}
myActivity
中。您还可以通过执行以下操作手动打开位置服务:

输入电话设置->选择“应用”->选择你的应用->选择“权限”选项->打开“位置”权限。

一旦用户启用了权限并启动了位置服务,您就可以开始扫描外设了。我注意到,如果您在启用权限/打开位置服务的同时已经在扫描,它仍然不会在扫描结果中放入任何内容。

这让公司可以看到你的位置,并指引你到他们想要的地方

在扫描设备时,一旦连接到BLE设备,您就可以关闭手机上的定位服务,并且您仍将保持与外围设备的连接。但是,一旦连接到固件(外围设备),在断开与配对设备的连接之前,您无法连接到任何新的外围设备,并且所有其他扫描设备(移动设备)无法在其扫描列表中看到外围设备名称(当用户搜索附近的外围设备时)当外围设备已经连接到任何其他移动设备时,因为外围设备一次只能连接到一个设备。
对于BLE基本样品,您可以检查此项。我想这段代码会解决你的问题。快乐编码:)

这个问题与我之前发布的内容有关。检查这些链接 ,

您需要两种方法:一种用于较旧的api,另一种用于最新的api


对于SDK 23及更高版本,您必须请求运行时权限。请求位置许可

可能只是Android手机的蓝牙芯片太差了。你看过hci日志了吗?还是logcat

蓝牙4.0芯片(在您的moto g中)有严格的限制,即您不能同时作为中央设备和外围设备,即使应始终允许扫描。因此,在BT4.0被淘汰之前,我不会生产一款依赖Android外围功能的产品


您应该使用至少有蓝牙4.1芯片的较新手机进行测试。

如果您将该应用程序用于非商业用途(意味着预期用户数不到5K),那么