kdb*_*las 14 android bluetooth bluetooth-lowenergy android-bluetooth
我正在扫描蓝牙LE设备并作为外围设备运行(在Moto G第二代上运行Android 6.0)
我遇到的问题是,有时(随机似乎但经常)它不会找到我的任何其他外围设备,其他时候它工作正常.
我有一个配套的iOS设备运行类似的代码(扫描外围设备和充当外围设备),当Android扫描无法找到iOS设备时,我的iOS发现Android设备充当外围设备就好了.因此,似乎只是扫描方面的问题.
它不仅仅是找不到我的配套iOS设备,而且找不到任何蓝牙设备.当它工作时,它会找到我的配套iOS设备以及许多其他设备.
我已经尝试过使用和不使用ScanFilters,并得到同样的问题.我正在使用最低SDK为23的SDK 26构建.
我正在设置所需的权限,因为它有时会起作用.
相关代码如下:
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);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我面临同样的问题。这是因为 Google 的政策已针对Marshmallow API 23及更高版本进行了更改,要使用 BLE 用户需要打开GPS。对于 Google 文档,请检查此Permission @ Runtime链接。要修复它,您必须在手机设置中启用“位置”,并在运行时在应用程序中请求位置权限。两者都需要完成才能使扫描正常工作。
要请求位置权限,请将以下内容放入对话框或类似内容中:
myActivity.requestPermissions(new String[]{Manifest.permission.ACCESS_COURSE_LOCATION}, yourPermissionRequestCode);
Run Code Online (Sandbox Code Playgroud)
并实施:
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] Results){
if(requestCode == yourPermissionRequestCode)
{
... //Do something based on Results
}
}
Run Code Online (Sandbox Code Playgroud)
在myActivity手柄无论用户选择。您还需要执行以下操作才能打开设备的定位服务:
Intent enableLocationIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
myActivity.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)
在myActivity。您还可以通过执行以下操作手动打开定位服务:
Enter phone settings -> Select "Apps" -> Select your app -> Select the "Permissions" option -> Switch the "Location" permission on.
一旦用户启用了权限并启动了定位服务,您就可以开始扫描外围设备。我注意到,如果您在启用许可/打开定位服务时已经在扫描,它仍然不会将任何内容放入您的onScanResults
这允许公司查看您的位置并将您定向到他们想要的地方。
在扫描设备时,一旦您连接到 BLE 设备,您就可以关闭手机上的定位服务,您仍将保持与外围设备的连接。但是,一旦您连接到固件(外设),您就无法再连接到任何新的外设,直到您断开与配对设备的连接,并且所有其他扫描设备(移动)都无法在其扫描列表中看到外设名称(当用户搜索附近的外围设备)当外围设备已经连接到任何其他移动设备时,因为外围设备一次只能连接到一个设备。对于 BLE 基本示例,您可以查看此Truiton Ble 教程。我认为这个片段将解决您的问题。快乐编码:)