@TargetApi(Build.VERSION_CODES.GINGERBREAD)
    public byte[] getBeaconAdvertisementData(Beacon beacon) {
        byte[] advertisingBytes;

        if (beacon.getIdentifiers().size() != getIdentifierCount()) {
            throw new IllegalArgumentException("Beacon has "+beacon.getIdentifiers().size()+" identifiers but format requires "+getIdentifierCount());
        }

        int lastIndex = -1;
        if (mMatchingBeaconTypeCodeEndOffset != null && mMatchingBeaconTypeCodeEndOffset > lastIndex) {
            lastIndex = mMatchingBeaconTypeCodeEndOffset;
        }
        if (mPowerEndOffset != null && mPowerEndOffset > lastIndex) {
            lastIndex = mPowerEndOffset;
        }
        for (int identifierNum = 0; identifierNum < this.mIdentifierEndOffsets.size(); identifierNum++) {
            if (this.mIdentifierEndOffsets.get(identifierNum) != null && this.mIdentifierEndOffsets.get(identifierNum) > lastIndex) {
                lastIndex = this.mIdentifierEndOffsets.get(identifierNum);
            }
        }
        for (int identifierNum = 0; identifierNum < this.mDataEndOffsets.size(); identifierNum++) {
            if (this.mDataEndOffsets.get(identifierNum) != null && this.mDataEndOffsets.get(identifierNum) > lastIndex) {
                lastIndex = this.mDataEndOffsets.get(identifierNum);
            }
        }

        // we must adjust the lastIndex to account for variable length identifiers, if there are any.
        int adjustedIdentifiersLength = 0;
        for (int identifierNum = 0; identifierNum < this.mIdentifierStartOffsets.size(); identifierNum++) {
            if (mIdentifierVariableLengthFlags.get(identifierNum)) {
                int declaredIdentifierLength = (this.mIdentifierEndOffsets.get(identifierNum) - this.mIdentifierStartOffsets.get(identifierNum)+1);
                int actualIdentifierLength = beacon.getIdentifier(identifierNum).getByteCount();
                adjustedIdentifiersLength += actualIdentifierLength;
                adjustedIdentifiersLength -= declaredIdentifierLength;
            }
        }
        lastIndex += adjustedIdentifiersLength;

        advertisingBytes = new byte[lastIndex+1-2];
        long beaconTypeCode = this.getMatchingBeaconTypeCode();

        // set type code
        for (int index = this.mMatchingBeaconTypeCodeStartOffset; index <= this.mMatchingBeaconTypeCodeEndOffset; index++) {
            byte value = (byte) (this.getMatchingBeaconTypeCode() >> (8*(this.mMatchingBeaconTypeCodeEndOffset-index)) & 0xff);
            advertisingBytes[index-2] = value;
        }

        // set identifiers
        for (int identifierNum = 0; identifierNum < this.mIdentifierStartOffsets.size(); identifierNum++) {
            byte[] identifierBytes = beacon.getIdentifier(identifierNum).toByteArrayOfSpecifiedEndianness(!this.mIdentifierLittleEndianFlags.get(identifierNum));

            // If the identifier we are trying to stuff into the space is different than the space available
            // adjust it
            if (identifierBytes.length < getIdentifierByteCount(identifierNum)) {
                if (!mIdentifierVariableLengthFlags.get(identifierNum)) {
                    // Pad it, but only if this is not a variable length identifier
                    if (mIdentifierLittleEndianFlags.get(identifierNum)) {
                        // this is little endian.  Pad at the end of the array
                        identifierBytes = Arrays.copyOf(identifierBytes,getIdentifierByteCount(identifierNum));
                    }
                    else {
                        // this is big endian.  Pad at the beginning of the array
                        byte[] newIdentifierBytes = new byte[getIdentifierByteCount(identifierNum)];
                        System.arraycopy(identifierBytes, 0, newIdentifierBytes, getIdentifierByteCount(identifierNum)-identifierBytes.length, identifierBytes.length);
                        identifierBytes = newIdentifierBytes;
                    }
                }
                LogManager.d(TAG, "Expanded identifier because it is too short.  It is now: "+byteArrayToString(identifierBytes));
            }
            else if (identifierBytes.length > getIdentifierByteCount(identifierNum)) {
                if (mIdentifierLittleEndianFlags.get(identifierNum)) {
                    // Truncate it at the beginning for big endian
                    identifierBytes = Arrays.copyOfRange(identifierBytes, getIdentifierByteCount(identifierNum)-identifierBytes.length, getIdentifierByteCount(identifierNum));
                }
                else {
                    // Truncate it at the end for little endian
                    identifierBytes = Arrays.copyOf(identifierBytes,getIdentifierByteCount(identifierNum));
                }
                LogManager.d(TAG, "Truncated identifier because it is too long.  It is now: "+byteArrayToString(identifierBytes));
            }
            else {
                LogManager.d(TAG, "Identifier size is just right: "+byteArrayToString(identifierBytes));
            }
            for (int index = this.mIdentifierStartOffsets.get(identifierNum); index <= this.mIdentifierStartOffsets.get(identifierNum)+identifierBytes.length-1; index ++) {
                advertisingBytes[index-2] = (byte) identifierBytes[index-this.mIdentifierStartOffsets.get(identifierNum)];
            }
        }

        // set power

        if (this.mPowerStartOffset != null && this.mPowerEndOffset != null) {
            for (int index = this.mPowerStartOffset; index <= this.mPowerEndOffset; index ++) {
                advertisingBytes[index-2] = (byte) (beacon.getTxPower() >> (8*(index - this.mPowerStartOffset)) & 0xff);
            }
        }

        // set data fields
        for (int dataFieldNum = 0; dataFieldNum < this.mDataStartOffsets.size(); dataFieldNum++) {
            long dataField = beacon.getDataFields().get(dataFieldNum);
            int dataFieldLength = this.mDataEndOffsets.get(dataFieldNum) - this.mDataStartOffsets.get(dataFieldNum);
            for (int index = 0; index <= dataFieldLength; index ++) {
                int endianCorrectedIndex = index;
                if (!this.mDataLittleEndianFlags.get(dataFieldNum)) {
                    endianCorrectedIndex = dataFieldLength-index;
                }
                advertisingBytes[this.mDataStartOffsets.get(dataFieldNum)-2+endianCorrectedIndex] = (byte) (dataField >> (8*index) & 0xff);
            }
        }
        return advertisingBytes;
    }
@ TargetApi ( Build . VERSION_CODES . GINGERBREAD ) public byte [ ] getBeaconAdvertisementData ( Beacon beacon ) { byte [ ] advertisingBytes ; if ( beacon . getIdentifiers ( ) . size ( ) != getIdentifierCount ( ) ) { throw new IllegalArgumentException ( "Beacon has " + beacon . getIdentifiers ( ) . size ( ) + " identifiers but format requires " + getIdentifierCount ( ) ) ; } int lastIndex = - 1 ; if ( mMatchingBeaconTypeCodeEndOffset != null && mMatchingBeaconTypeCodeEndOffset > lastIndex ) { lastIndex = mMatchingBeaconTypeCodeEndOffset ; } if ( mPowerEndOffset != null && mPowerEndOffset > lastIndex ) { lastIndex = mPowerEndOffset ; } for ( int identifierNum = 0 ; identifierNum < this . mIdentifierEndOffsets . size ( ) ; identifierNum ++ ) { if ( this . mIdentifierEndOffsets . get ( identifierNum ) != null && this . mIdentifierEndOffsets . get ( identifierNum ) > lastIndex ) { lastIndex = this . mIdentifierEndOffsets . get ( identifierNum ) ; } } for ( int identifierNum = 0 ; identifierNum < this . mDataEndOffsets . size ( ) ; identifierNum ++ ) { if ( this . mDataEndOffsets . get ( identifierNum ) != null && this . mDataEndOffsets . get ( identifierNum ) > lastIndex ) { lastIndex = this . mDataEndOffsets . get ( identifierNum ) ; } } int adjustedIdentifiersLength = 0 ; for ( int identifierNum = 0 ; identifierNum < this . mIdentifierStartOffsets . size ( ) ; identifierNum ++ ) { if ( mIdentifierVariableLengthFlags . get ( identifierNum ) ) { int declaredIdentifierLength = ( this . mIdentifierEndOffsets . get ( identifierNum ) - this . mIdentifierStartOffsets . get ( identifierNum ) + 1 ) ; int actualIdentifierLength = beacon . getIdentifier ( identifierNum ) . getByteCount ( ) ; adjustedIdentifiersLength += actualIdentifierLength ; adjustedIdentifiersLength -= declaredIdentifierLength ; } } lastIndex += adjustedIdentifiersLength ; advertisingBytes = new byte [ lastIndex + 1 - 2 ] ; long beaconTypeCode = this . getMatchingBeaconTypeCode ( ) ; for ( int index = this . mMatchingBeaconTypeCodeStartOffset ; index <= this . mMatchingBeaconTypeCodeEndOffset ; index ++ ) { byte value = ( byte ) ( this . getMatchingBeaconTypeCode ( ) > > ( 8 * ( this . mMatchingBeaconTypeCodeEndOffset - index ) ) & 0xff ) ; advertisingBytes [ index - 2 ] = value ; } for ( int identifierNum = 0 ; identifierNum < this . mIdentifierStartOffsets . size ( ) ; identifierNum ++ ) { byte [ ] identifierBytes = beacon . getIdentifier ( identifierNum ) . toByteArrayOfSpecifiedEndianness ( ! this . mIdentifierLittleEndianFlags . get ( identifierNum ) ) ; if ( identifierBytes . length < getIdentifierByteCount ( identifierNum ) ) { if ( ! mIdentifierVariableLengthFlags . get ( identifierNum ) ) { if ( mIdentifierLittleEndianFlags . get ( identifierNum ) ) { identifierBytes = Arrays . copyOf ( identifierBytes , getIdentifierByteCount ( identifierNum ) ) ; } else { byte [ ] newIdentifierBytes = new byte [ getIdentifierByteCount ( identifierNum ) ] ; System . arraycopy ( identifierBytes , 0 , newIdentifierBytes , getIdentifierByteCount ( identifierNum ) - identifierBytes . length , identifierBytes . length ) ; identifierBytes = newIdentifierBytes ; } } LogManager . d ( TAG , "Expanded identifier because it is too short.  It is now: " + byteArrayToString ( identifierBytes ) ) ; } else if ( identifierBytes . length > getIdentifierByteCount ( identifierNum ) ) { if ( mIdentifierLittleEndianFlags . get ( identifierNum ) ) { identifierBytes = Arrays . copyOfRange ( identifierBytes , getIdentifierByteCount ( identifierNum ) - identifierBytes . length , getIdentifierByteCount ( identifierNum ) ) ; } else { identifierBytes = Arrays . copyOf ( identifierBytes , getIdentifierByteCount ( identifierNum ) ) ; } LogManager . d ( TAG , "Truncated identifier because it is too long.  It is now: " + byteArrayToString ( identifierBytes ) ) ; } else { LogManager . d ( TAG , "Identifier size is just right: " + byteArrayToString ( identifierBytes ) ) ; } for ( int index = this . mIdentifierStartOffsets . get ( identifierNum ) ; index <= this . mIdentifierStartOffsets . get ( identifierNum ) + identifierBytes . length - 1 ; index ++ ) { advertisingBytes [ index - 2 ] = ( byte ) identifierBytes [ index - this . mIdentifierStartOffsets . get ( identifierNum ) ] ; } } if ( this . mPowerStartOffset != null && this . mPowerEndOffset != null ) { for ( int index = this . mPowerStartOffset ; index <= this . mPowerEndOffset ; index ++ ) { advertisingBytes [ index - 2 ] = ( byte ) ( beacon . getTxPower ( ) > > ( 8 * ( index - this . mPowerStartOffset ) ) & 0xff ) ; } } for ( int dataFieldNum = 0 ; dataFieldNum < this . mDataStartOffsets . size ( ) ; dataFieldNum ++ ) { long dataField = beacon . getDataFields ( ) . get ( dataFieldNum ) ; int dataFieldLength = this . mDataEndOffsets . get ( dataFieldNum ) - this . mDataStartOffsets . get ( dataFieldNum ) ; for ( int index = 0 ; index <= dataFieldLength ; index ++ ) { int endianCorrectedIndex = index ; if ( ! this . mDataLittleEndianFlags . get ( dataFieldNum ) ) { endianCorrectedIndex = dataFieldLength - index ; } advertisingBytes [ this . mDataStartOffsets . get ( dataFieldNum ) - 2 + endianCorrectedIndex ] = ( byte ) ( dataField > > ( 8 * index ) & 0xff ) ; } } return advertisingBytes ; }
Get BLE advertisement bytes for a Beacon
@param beacon the beacon containing the data to be transmitted
@return the byte array of the advertisement