Communicating between iOS and Android with Bluetooth LE

后端 未结 6 608
遥遥无期
遥遥无期 2020-11-28 18:15

I\'ve got a working app using CoreBluetooth to communicate between an iPad (central) and iPhone (peripheral). I have one service that has two characteristics. I have a Nexus

6条回答
  •  被撕碎了的回忆
    2020-11-28 18:52

    I've written a simple working example, well relatively simple, and included it open-source on Github: https://github.com/GitGarage. So far it has only been tested with an Android Nexus 9 and an iPhone 5s, but I presume it would also work with a Nexus 6 and various iPhone types. So far it is set up explicitly to communicate between one Android and one iPhone, but I presume it is tweakable to do much more.

    Here are the key methods...

    DROID SIDE - Sending to iOS:

    private void sendMessage() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                if (mBTAdapter == null) {
                    return;
                }
                if (mBTAdvertiser == null) {
                    mBTAdvertiser = mBTAdapter.getBluetoothLeAdvertiser();
                }
                   // get the full message from the UI
                String textMessage = mEditText.getText().toString(); 
                if (textMessage.length() > 0)
                {
                       // add 'Android' as the user name
                    String message = "Android: " + textMessage; 
    
                    while (message.length() > 0) {
                        String subMessage;
                        if(message.length() > 8)
                        {    // add dash to unfinished messages
                            subMessage = message.substring(0,8) + "-"; 
                            message = message.substring(8);
                            for (int i = 0; i < 20; i++) // twenty times (better safe than sorry) send this part of the message. duplicate parts will be ignored
                            {
                                AdvertiseData ad = BleUtil.makeAdvertiseData(subMessage);
                                mBTAdvertiser.startAdvertising(BleUtil.createAdvSettings(true, 100), ad, mAdvCallback);
                                mBTAdvertiser.stopAdvertising(mAdvCallback);
                            }
                        }
                        else
                        {  // otherwise, send the last part
                            subMessage = message;
                            message = "";
                            for (int i = 0; i < 5; i++)
                            {
                                AdvertiseData ad = BleUtil.makeAdvertiseData(subMessage);
                                mBTAdvertiser.startAdvertising(
                                        BleUtil.createAdvSettings(true, 40), ad,
                                        mAdvCallback);
                                mBTAdvertiser.stopAdvertising(mAdvCallback);
                            }
                        }
                    }
                    threadHandler.post(updateRunnable);
                }
            }
        });
        thread.start();
    }
    

    DROID SIDE - Receiving from iOS:

    @Override
    public void onLeScan(final BluetoothDevice newDevice, final int newRssi,
                         final byte[] newScanRecord) {
    
        int startByte = 0;
        String hex = asHex(newScanRecord).substring(0,29);
           // check five times, startByte was used for something else before
        while (startByte <= 5) {
           // check if this is a repeat message
            if (!Arrays.asList(used).contains(hex)) {
                used[ui] = hex;
    
                String message = new String(newScanRecord);
                String firstChar = message.substring(5, 6);
                Pattern pattern = Pattern.compile("[ a-zA-Z0-9~!@#$%^&*()_+{}|:\"<>?`\\-=;',\\./\\[\\]\\\\]", Pattern.DOTALL);
                   // if the message is comprised of standard characters...
                Matcher matcher = pattern.matcher(firstChar);
                if (firstChar.equals("L"))
                {
                    firstChar = message.substring(6, 7);
                    pattern = Pattern.compile("[ a-zA-Z0-9~!@#$%^&*()_+{}|:\"<>?`\\-=;',\\./\\[\\]\\\\]", Pattern.DOTALL);
                    matcher = pattern.matcher(firstChar);
                }
    
                if(matcher.matches())
                {
                    TextView textViewToChange = (TextView) findViewById(R.id.textView);
                    String oldText = textViewToChange.getText().toString();
                    int len = 0;
                    String subMessage = "";
                       // add this portion to our final message
                    while (matcher.matches())  
                    {
                        subMessage = message.substring(5, 6+len);
                        matcher = pattern.matcher(message.substring(5+len, 6+len));
                        len++;
                    }
                    subMessage = subMessage.substring(0,subMessage.length()-1);
    
                    Log.e("Address",newDevice.getAddress());
                    Log.e("Data",asHex(newScanRecord));
                    boolean enter = subMessage.length() == 16;
                    enter = enter && !subMessage.substring(15).equals("-");
                    enter = enter || subMessage.length() < 16;
                    textViewToChange.setText(oldText + subMessage.substring(0, subMessage.length() - 1) + (enter ? "\n" : ""));
                    ui = ui == 2 ? -1 : ui;
                    ui++;
    
                    Log.e("String", subMessage);
                }
                break;
            }
            startByte++;
        }
    }
    

    iOS SIDE - Sending to Android:

    func startAdvertisingToPeripheral() {
        var allTime:UInt64 = 0;
        if (dataToSend != nil)
        {
            datastring = NSString(data:dataToSend, encoding:NSUTF8StringEncoding) as String
            datastring = "iPhone: " + datastring
            if (datastring.length > 15)
            {
                for (var i:Double = 0; i < Double(datastring.length)/15.000; i++)
                {
                    let delay = i/10.000 * Double(NSEC_PER_SEC)
                    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
                    allTime = time
                    dispatch_after(time, dispatch_get_main_queue(), { () -> Void in self.sendPart() });
                }
            }
            else
            {
                var messageUUID = StringToUUID(datastring)
                if !peripheralManager.isAdvertising {
                    peripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey: [CBUUID(string: messageUUID)]])
                }
            }
        }
    }
    

    iOS SIDE - Receiving from Android:

    func centralManager(central: CBCentralManager!, didDiscoverPeripheral peripheral: CBPeripheral!, advertisementData: [NSObject : AnyObject]!, RSSI: NSNumber!) {
    
        delegate?.didDiscoverPeripheral(peripheral)
        var splitUp = split("\(advertisementData)") {$0 == "\n"}
        if (splitUp.count > 1)
        {
            var chop = splitUp[1]
            chop = chop[0...chop.length-2]
            var chopSplit = split("\(chop)") {$0 == "\""}
    
            if !(chopSplit.count > 1 && chopSplit[1] == "Device Information")
            {
                var hexString = chop[4...7] + chop[12...19] + chop[21...26]
                var datas = hexString.dataFromHexadecimalString()
                var string = NSString(data: datas!, encoding: NSUTF8StringEncoding) as String
                if (!contains(usedList,string))
                {
                    usedList.append(string)
                    if (string.length == 9 && string[string.length-1...string.length-1] == "-")
                    {
                        finalString = finalString + string[0...string.length-2]
                    }
                    else
                    {
                        lastString = finalString + string + "\n"
                        println(lastString)
                        finalString = ""
                        usedList = newList
                        usedList.append(string)
                    }
                }
            }
        }
    }
    

提交回复
热议问题