Android 低功耗蓝牙屏蔽 UUID 过滤器
Android Bluetooth LE Masked UUID Filter
我正在尝试 Android 和 iOS 的实验性 Bluetooth LE
程序,现在我在 Android 端过滤信标广告时遇到一些问题iOS 方发出。 Android 具有通过带掩码的 UUID 过滤广告的功能(我需要这个,因为我试图让 UUID 以特定值开头)但我无法让它工作。这是我正在尝试的:
private void freshen() {
// kill current scanner
if (mLEScanner != null)
mLEScanner.stopScan(mScanCallback);
// set new one to be a match scanner
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
List<ScanFilter> filters = new ArrayList<>();
// create data uuid starting with the value 1
ParcelUuid data = ParcelUuid.fromString("10000000-0000-0000-0000-000000000000");
// create a mask to ensure only that value is searched
ParcelUuid mask = ParcelUuid.fromString("10000000-0000-0000-0000-000000000000");
// build the filter
ScanFilter.Builder builder = new ScanFilter.Builder();
builder.setServiceUuid(data, mask);
ScanFilter filter = builder.build();
// add the filter to the scanner
filters.add(filter);
mLEScanner.startScan(filters, settings, mScanCallback);
}
结果为零。即使我将所有掩码值设置为 0(这是忽略的数字),它仍然会产生零结果。当我删除过滤器时,会出现大量以 1 开头的结果。这在 Android 的当前版本中是否已损坏?
这不是解决此问题的方法,但我决定改为按 DeviceName 进行过滤,因为这可以由 Android 和 iOS 端填充。现在我专注于 iOS 到 Android 通信 =>
iOS:
func centralManager(_: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi: NSNumber){
delegate?.didDiscoverPeripheral(peripheral)
let splitUp : [String] = "\(advertisementData)".components(separatedBy: "\n")
if (splitUp.count > 1)
{
var chop = splitUp[1]
let counter = chop.characters.count - 2
chop = chop[0..<counter]
let chopSplit : [String] = "\(chop)".components(separatedBy: "\"")
if !(chopSplit.count > 1 && chopSplit[1] == "Device Information" && !sending)
{
let hexString = chop[4..<7] + chop[12..<19] + chop[21..<26]
let hexArray = [hexString[0..<1], hexString[2..<3], hexString[4..<5], hexString[6..<7], hexString[8..<9], hexString[10..<11], hexString[12..<13], hexString[14..<15], hexString[16..<17]]
let charArray = hexArray.map { Character(hexToScalar(char: [=10=])) }
let string = String(charArray) as String
if (string == "GoTcHa" + stringify(number: writing))
{
writing += 1
let messageUUID = StringToUUID(hex: String(writing) + "hello" + String(writing))
peripheralManager.stopAdvertising()
let name = String(writing) as NSString
peripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey: [CBUUID(string: messageUUID)], CBAdvertisementDataLocalNameKey: name])
}
}
}
}
func StringToUUID(hex: String) -> String
{
var rev = String(hex.characters.reversed())
let hexData: NSData! = rev.data(using: String.Encoding.utf8, allowLossyConversion: false) as NSData!
rev = hexData.toHexString()
while(rev.characters.count < 31) {
rev = "0" + rev;
}
rev = String(writing % 10) + rev[0..<30]
let finalString = rev[0..<7] + "-" + rev[8..<11] + "-" + rev[12..<15] + "-" + rev[16..<19] + "-" + rev[20..<31]
return finalString
}
更重要的是 Android 扫描方法,它现在忽略来自 iOS 的重复消息,始终通过设备名称查找下一条消息:
private void freshen() {
if (mLEScanner != null)
mLEScanner.stopScan(mScanCallback);
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
.build();
List<ScanFilter> filters = new ArrayList<>();
ScanFilter filter = new ScanFilter.Builder()
.setDeviceName("" + (reading % 10))
.build();
filters.add(filter);
mLEScanner.startScan(filters, settings, mScanCallback);
}
我现在需要让 iOS 端更好地过滤 Android 的响应,但它在 Android 接收端有效。
我正在尝试 Android 和 iOS 的实验性 Bluetooth LE
程序,现在我在 Android 端过滤信标广告时遇到一些问题iOS 方发出。 Android 具有通过带掩码的 UUID 过滤广告的功能(我需要这个,因为我试图让 UUID 以特定值开头)但我无法让它工作。这是我正在尝试的:
private void freshen() {
// kill current scanner
if (mLEScanner != null)
mLEScanner.stopScan(mScanCallback);
// set new one to be a match scanner
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
List<ScanFilter> filters = new ArrayList<>();
// create data uuid starting with the value 1
ParcelUuid data = ParcelUuid.fromString("10000000-0000-0000-0000-000000000000");
// create a mask to ensure only that value is searched
ParcelUuid mask = ParcelUuid.fromString("10000000-0000-0000-0000-000000000000");
// build the filter
ScanFilter.Builder builder = new ScanFilter.Builder();
builder.setServiceUuid(data, mask);
ScanFilter filter = builder.build();
// add the filter to the scanner
filters.add(filter);
mLEScanner.startScan(filters, settings, mScanCallback);
}
结果为零。即使我将所有掩码值设置为 0(这是忽略的数字),它仍然会产生零结果。当我删除过滤器时,会出现大量以 1 开头的结果。这在 Android 的当前版本中是否已损坏?
这不是解决此问题的方法,但我决定改为按 DeviceName 进行过滤,因为这可以由 Android 和 iOS 端填充。现在我专注于 iOS 到 Android 通信 =>
iOS:
func centralManager(_: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi: NSNumber){
delegate?.didDiscoverPeripheral(peripheral)
let splitUp : [String] = "\(advertisementData)".components(separatedBy: "\n")
if (splitUp.count > 1)
{
var chop = splitUp[1]
let counter = chop.characters.count - 2
chop = chop[0..<counter]
let chopSplit : [String] = "\(chop)".components(separatedBy: "\"")
if !(chopSplit.count > 1 && chopSplit[1] == "Device Information" && !sending)
{
let hexString = chop[4..<7] + chop[12..<19] + chop[21..<26]
let hexArray = [hexString[0..<1], hexString[2..<3], hexString[4..<5], hexString[6..<7], hexString[8..<9], hexString[10..<11], hexString[12..<13], hexString[14..<15], hexString[16..<17]]
let charArray = hexArray.map { Character(hexToScalar(char: [=10=])) }
let string = String(charArray) as String
if (string == "GoTcHa" + stringify(number: writing))
{
writing += 1
let messageUUID = StringToUUID(hex: String(writing) + "hello" + String(writing))
peripheralManager.stopAdvertising()
let name = String(writing) as NSString
peripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey: [CBUUID(string: messageUUID)], CBAdvertisementDataLocalNameKey: name])
}
}
}
}
func StringToUUID(hex: String) -> String
{
var rev = String(hex.characters.reversed())
let hexData: NSData! = rev.data(using: String.Encoding.utf8, allowLossyConversion: false) as NSData!
rev = hexData.toHexString()
while(rev.characters.count < 31) {
rev = "0" + rev;
}
rev = String(writing % 10) + rev[0..<30]
let finalString = rev[0..<7] + "-" + rev[8..<11] + "-" + rev[12..<15] + "-" + rev[16..<19] + "-" + rev[20..<31]
return finalString
}
更重要的是 Android 扫描方法,它现在忽略来自 iOS 的重复消息,始终通过设备名称查找下一条消息:
private void freshen() {
if (mLEScanner != null)
mLEScanner.stopScan(mScanCallback);
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
.build();
List<ScanFilter> filters = new ArrayList<>();
ScanFilter filter = new ScanFilter.Builder()
.setDeviceName("" + (reading % 10))
.build();
filters.add(filter);
mLEScanner.startScan(filters, settings, mScanCallback);
}
我现在需要让 iOS 端更好地过滤 Android 的响应,但它在 Android 接收端有效。