Java Android 蓝牙 LE 屏蔽 UUID 过滤器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39823416/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:28:23  来源:igfitidea点击:

Android Bluetooth LE Masked UUID Filter

javaandroidfilterbluetooth-lowenergy

提问by omikes

I am playing around with an experimental Bluetooth LEprogram for Android and iOS, and right now I am having some trouble on the Android side filtering beacon advertisements sent out by the iOS side. Android has a feature to filter advertisements by UUID with a mask (I need this as I am trying to get UUIDs beginning with a specific value) but I can't get it to work. Here's what I am trying:

我正在玩一个Bluetooth LE适用于 Android 和 iOS的实验程序,现在我在 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);
}

It is producing zero results. Even if I set all mask values to 0 (which is the number for ignore) it still produces zero results. When I remove the filter, plenty of results beginning with 1 appear. Is this broken in the current version of Android?

它正在产生零结果。即使我将所有掩码值设置为 0(这是忽略的数字),它仍然会产生零结果。当我移除过滤器时,会出现大量以 1 开头的结果。这在当前版本的 Android 中是否已损坏?

采纳答案by omikes

Its not a fix for this problem, but I decided to filter by DeviceName instead, as this can be populated by both the Android and iOS sides. Right now I am focusing on iOS to Android communication =>

这不是解决此问题的方法,但我决定改为按 DeviceName 进行过滤,因为这可以由 Android 和 iOS 端填充。现在我专注于 iOS 到 Android 的通信 =>

iOS:

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: 
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);
}
)) } 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 }

And more importantly the Android scanning method, which now ignores duplicate messages from iOS by always looking for the next message through the DeviceName:

更重要的是 Android 扫描方法,它现在通过始终通过 DeviceName 查找下一条消息来忽略来自 iOS 的重复消息:

##代码##

I need to get the iOS side to filter Android's responses better now, but it is effective on the Android receiving side.

我现在需要让 iOS 端更好地过滤 Android 的响应,但它在 Android 接收端是有效的。