【问题标题】:Android Bluetooth LE Masked UUID FilterAndroid 蓝牙 LE 屏蔽 UUID 过滤器
【发布时间】:2017-02-10 21:57:09
【问题描述】:

我正在玩一个适用于 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 中是否存在问题?

【问题讨论】:

    标签: java android filter bluetooth-lowenergy


    【解决方案1】:

    这不是解决此问题的方法,但我决定改为按 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: $0)) }
                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 扫描方法,现在通过始终通过 DeviceName 查找下一条消息来忽略来自 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 接收端有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-25
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-26
      相关资源
      最近更新 更多