private void sendBeaconChangeMessage(Beacon beacon) { String uuid = beacon.getId1().toString(); // Payload SaneJSONObject payload = new SaneJSONObject(); payload.putOrIgnore("platform", "android"); payload.putDoubleOrIgnore("version", VERSION); // Beacon SaneJSONObject beaconJSON = new SaneJSONObject(); beaconJSON.putOrIgnore("uuid", uuid); payload.putJSONOrIgnore("beacon", beaconJSON); // Proximity payload.putJSONOrIgnore("proximity", getProximity(beacon)); // Message SaneJSONObject message = new SaneJSONObject(); JSONArray devices = new JSONArray(); devices.put("*"); message.putArrayOrIgnore("devices", devices); message.putJSONOrIgnore("payload", payload); message.putOrIgnore("topic", "location_update"); // Send BeaconInfo beaconInfo = getBeaconInfo(this.beaconInfo, uuid); Double distance = beacon.getDistance(); if (beaconInfo.hasChangedDistance(distance)) { meshblu.message(message); emitter.emit(EVENTS.LOCATION_UPDATE, payload, beaconInfo); } beaconInfo.setLastDistance(distance); }
/** * Estimate the distance to the beacon using the DistanceCalculator set on this class. If no * DistanceCalculator has been set, return -1 as the distance. * * @see org.altbeacon.beacon.distance.DistanceCalculator * @param txPower * @param bestRssiAvailable * @return */ protected static Double calculateDistance(int txPower, double bestRssiAvailable) { if (Beacon.getDistanceCalculator() != null) { return Beacon.getDistanceCalculator().calculateDistance(txPower, bestRssiAvailable); } else { LogManager.e(TAG, "Distance calculator not set. Distance will bet set to -1"); return -1.0; } }
/** * 每个扫描周期结束,根据20秒内各beacon的RSSI平均值计算它的距离,该回调获取这些beacon的距离值 Called once per second (实际上是每扫描周期) * to give an estimate of the mDistance to visible beacons */ @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { LogManager.d(TAG, "didRangeBeaconsInRegion(),beacons=" + beacons.size()); for (Beacon beacon : beacons) { LogManager.d(TAG, beacon.getId2() + ":" + beacon.getId3() + "," + beacon.getDistance()); } Beacon beacon = mNearestBeacon.getNearestBeacon(mGetBeaconType, beacons); mOnNearestBeaconListener.getNearestBeacon(mGetBeaconType, beacon); }
/** * @param beacon the beacon whose fields we should copy to this beacon builder * @return */ public Builder copyBeaconFields(Beacon beacon) { setIdentifiers(beacon.getIdentifiers()); setBeaconTypeCode(beacon.getBeaconTypeCode()); setDataFields(beacon.getDataFields()); setBluetoothAddress(beacon.getBluetoothAddress()); setBluetoothName(beacon.getBluetoothName()); setExtraDataFields(beacon.getExtraDataFields()); setManufacturer(beacon.getManufacturer()); setTxPower(beacon.getTxPower()); setRssi(beacon.getRssi()); setServiceUuid(beacon.getServiceUuid()); return this; }
@Test public void gattBeaconExtraDataAreNotOverwritten() { Beacon beacon = getGattBeacon(); Beacon extraDataBeacon = getGattBeaconExtraData(); GattBeaconTracker tracker = new GattBeaconTracker(); tracker.track(beacon); tracker.track(extraDataBeacon); Beacon trackedBeacon = tracker.track(beacon); assertEquals( "extra data should not be overwritten", extraDataBeacon.getDataFields(), trackedBeacon.getExtraDataFields()); }
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { if (beacons.size() > 0) { EditText editText = (EditText) RangingActivity.this.findViewById(R.id.rangingText); for (Beacon beacon : beacons) { logToDisplay( "Beacon " + beacon.toString() + " is about " + beacon.getDistance() + " meters away, with Rssi: " + beacon.getRssi()); } } }
@Override public void getBeacons(Collection<Beacon> beacons) { // 防止停止收集beacons前,再次收到此回调,导致重复记录,在开始和结束监控(查找)beacons时设置。 if (isRecorded) return; // 已经记录了 // 日志记录和屏幕显示Beacon信息 // 有可能到达采样周期时,没有找到所有beacons,甚至是0个beacons,因此,应重复记录,一直到采样周期结束。当然是最后更新的有效。 String str = "beacons=" + beacons.size(); LogManager.d(TAG, str); logToDisplay(str); String rssi; for (Beacon beacon : beacons) { // becaon的两个id(major,minor),rssi及其平均值 str = beacon.getId2() + ":" + beacon.getId3() + "=" + beacon.getRssi() + "," + String.format("%.2f", beacon.getRunningAverageRssi()); LogManager.d(TAG, str); logToDisplay(str); // 记录至mBeaconsRssi rssi = beacon.getId2() + "_" + beacon.getId3() + ":" + String.format("%.2f", beacon.getRunningAverageRssi()); mBeaconsRssi.put(beacon, rssi); } // 记录参考点的各个beacon的id和rssi平均值 if ((System.currentTimeMillis() - startSample) >= SamplePeroid) { // 将目前定位参考点测量的各个beacons的rssi平均值计入数据库。 SaveRssiToDb(); str = "记录完毕,定位参考点[" + reference_pointPerf + reference_pointNum + "]" + "各个beacon的rssi平均值"; LogManager.d(TAG, str); logToDisplay(str); // 以下必须在UI现成中执行,否则,程序将异常终止。 runOnUiThread( new Runnable() { public void run() { String str = "记录完毕,定位参考点[" + reference_pointPerf + reference_pointNum + "]"; Toast.makeText(trainingActivity.this, str, Toast.LENGTH_LONG).show(); // 下一个参考点默认名称 reference_pointNum++; reference_point_edit.setText(reference_pointPerf + reference_pointNum); // 停止查找beacons onMonitoringStop(null); } }); } }
@Test public void gattBeaconExtraDataGetUpdated() { Beacon beacon = getGattBeacon(); Beacon extraDataBeacon = getGattBeaconExtraData(); Beacon extraDataBeacon2 = getGattBeaconExtraData2(); GattBeaconTracker tracker = new GattBeaconTracker(); tracker.track(beacon); tracker.track(extraDataBeacon); tracker.track(extraDataBeacon2); Beacon trackedBeacon = tracker.track(beacon); assertEquals( "extra data is updated", extraDataBeacon2.getDataFields(), trackedBeacon.getExtraDataFields()); }
/** * @see Beacon#mIdentifiers * @param identifiers identifiers to set * @return builder */ public Builder setIdentifiers(List<Identifier> identifiers) { mId1 = null; mId2 = null; mId3 = null; mBeacon.mIdentifiers = identifiers; return this; }
private void beaconRangeChange(Collection<Beacon> beacons, Region region) { for (Beacon beacon : beacons) { String uuid = beacon.getId1().toString(); DecimalFormat df = new DecimalFormat("#.000"); String distance = df.format(beacon.getDistance()); Log.d(TAG, "Beacon (" + uuid.substring(0, 8) + ") is about " + distance + " meters away."); Boolean enabled = isBeaconEnabled(uuid); if (enabled != null) { if (enabled) { sendBeaconChangeMessage(beacon); } } else { emitter.emit(EVENTS.DISCOVERED_BEACON, beacon); } } }
/** * Two detected beacons are considered equal if they share the same three identifiers, regardless * of their mDistance or RSSI. */ @Override public boolean equals(Object that) { if (!(that instanceof Beacon)) { return false; } Beacon thatBeacon = (Beacon) that; if (this.mIdentifiers.size() != thatBeacon.mIdentifiers.size()) { return false; } // all identifiers must match for (int i = 0; i < this.mIdentifiers.size(); i++) { if (!this.mIdentifiers.get(i).equals(thatBeacon.mIdentifiers.get(i))) { return false; } } return sHardwareEqualityEnforced ? this.getBluetoothAddress().equals(thatBeacon.getBluetoothAddress()) : true; }
private SaneJSONObject getProximity(Beacon beacon) { Double distance = beacon.getDistance(); String proximity = "Unknown"; Integer code = 0; if (distance < 2) { code = 1; proximity = "Immediate"; } else if (distance >= 2 && distance < 5) { code = 2; proximity = "Near"; } else if (distance >= 5) { code = 3; proximity = "Far"; } SaneJSONObject proximityJSON = new SaneJSONObject(); proximityJSON.putOrIgnore("message", proximity); proximityJSON.putIntOrIgnore("code", code); proximityJSON.putDoubleOrIgnore("distance", distance); proximityJSON.putIntOrIgnore("rssi", beacon.getRssi()); Long time = new Date().getTime(); proximityJSON.putOrIgnore("timestamp", new Timestamp(time).toString()); return proximityJSON; }
/** * Copy constructor * * @param otherBeacon */ protected Beacon(Beacon otherBeacon) { super(); mIdentifiers = new ArrayList<Identifier>(otherBeacon.mIdentifiers.size()); mDataFields = new ArrayList<Long>(otherBeacon.mDataFields.size()); mExtraDataFields = new ArrayList<Long>(otherBeacon.mExtraDataFields.size()); for (int i = 0; i < otherBeacon.mIdentifiers.size(); i++) { mIdentifiers.add(otherBeacon.mIdentifiers.get(i)); } for (int i = 0; i < otherBeacon.mDataFields.size(); i++) { mDataFields.add(otherBeacon.mDataFields.get(i)); } for (int i = 0; i < otherBeacon.mExtraDataFields.size(); i++) { mExtraDataFields.add(otherBeacon.mExtraDataFields.get(i)); } this.mDistance = otherBeacon.mDistance; this.mRunningAverageRssi = otherBeacon.mRunningAverageRssi; this.mRssi = otherBeacon.mRssi; this.mTxPower = otherBeacon.mTxPower; this.mBluetoothAddress = otherBeacon.mBluetoothAddress; this.mBeaconTypeCode = otherBeacon.getBeaconTypeCode(); this.mServiceUuid = otherBeacon.getServiceUuid(); this.mBluetoothName = otherBeacon.mBluetoothName; }
@Test public void gattBeaconFieldsGetUpdated() { Beacon beacon = getGattBeacon(); Beacon beaconUpdate = getGattBeaconUpdate(); Beacon extraDataBeacon = getGattBeaconExtraData(); GattBeaconTracker tracker = new GattBeaconTracker(); tracker.track(beacon); Beacon trackedBeacon = tracker.track(beaconUpdate); assertEquals("rssi should be updated", beaconUpdate.getRssi(), trackedBeacon.getRssi()); assertEquals( "data fields should be updated", beaconUpdate.getDataFields(), trackedBeacon.getDataFields()); }
/** * @see Beacon#mTxPower * @param txPower * @return builder */ public Builder setTxPower(int txPower) { mBeacon.mTxPower = txPower; return this; }
/** * @see Beacon#mBluetoothName * @param name * @return builder */ public Builder setBluetoothName(String name) { mBeacon.mBluetoothName = name; return this; }
/** * @see Beacon#mManufacturer * @param manufacturer * @return builder */ public Builder setManufacturer(int manufacturer) { mBeacon.mManufacturer = manufacturer; return this; }
/** * @see Beacon#mDataFields * @param extraDataFields * @return builder */ public Builder setExtraDataFields(List<Long> extraDataFields) { mBeacon.mExtraDataFields = extraDataFields; return this; }
/** * @see Beacon#mDataFields * @param dataFields * @return builder */ public Builder setDataFields(List<Long> dataFields) { mBeacon.mDataFields = dataFields; return this; }
/** * @see Beacon#mBluetoothAddress * @param bluetoothAddress * @return builder */ public Builder setBluetoothAddress(String bluetoothAddress) { mBeacon.mBluetoothAddress = bluetoothAddress; return this; }
/** * @see Beacon#mServiceUuid * @param serviceUuid * @return builder */ public Builder setServiceUuid(int serviceUuid) { mBeacon.mServiceUuid = serviceUuid; return this; }
/** * @see Beacon#mBeaconTypeCode * @param beaconTypeCode * @return builder */ public Builder setBeaconTypeCode(int beaconTypeCode) { mBeacon.mBeaconTypeCode = beaconTypeCode; return this; }
/** * Get BLE advertisement bytes for a Beacon * * @param beacon the beacon containing the data to be transmitted * @return the byte array of the advertisement */ @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 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); for (int index = this.mDataStartOffsets.get(dataFieldNum); index <= this.mDataEndOffsets.get(dataFieldNum); index++) { int endianCorrectedIndex = index; if (this.mDataLittleEndianFlags.get(dataFieldNum)) { endianCorrectedIndex = this.mDataEndOffsets.get(dataFieldNum) - index; } advertisingBytes[endianCorrectedIndex - 2] = (byte) (dataField >> (8 * (index - this.mDataStartOffsets.get(dataFieldNum))) & 0xff); } } return advertisingBytes; }
/** * @see Beacon#mRssi * @param rssi * @return builder */ public Builder setRssi(int rssi) { mBeacon.mRssi = rssi; return this; }
@TargetApi(5) protected Beacon fromScanData( byte[] bytesToProcess, int rssi, BluetoothDevice device, Beacon beacon) { BleAdvertisement advert = new BleAdvertisement(bytesToProcess); boolean parseFailed = false; Pdu pduToParse = null; int startByte = 0; ArrayList<Identifier> identifiers = new ArrayList<Identifier>(); ArrayList<Long> dataFields = new ArrayList<Long>(); for (Pdu pdu : advert.getPdus()) { if (pdu.getType() == Pdu.GATT_SERVICE_UUID_PDU_TYPE || pdu.getType() == Pdu.MANUFACTURER_DATA_PDU_TYPE) { pduToParse = pdu; if (LogManager.isVerboseLoggingEnabled()) { LogManager.d( TAG, "Processing pdu type %02X: %s with startIndex: %d, endIndex: %d", pdu.getType(), bytesToHex(bytesToProcess), pdu.getStartIndex(), pdu.getEndIndex()); } break; } else { if (LogManager.isVerboseLoggingEnabled()) { LogManager.d(TAG, "Ignoring pdu type %02X", pdu.getType()); } } } if (pduToParse == null) { if (LogManager.isVerboseLoggingEnabled()) { LogManager.d(TAG, "No PDUs to process in this packet."); } parseFailed = true; } else { byte[] serviceUuidBytes = null; byte[] typeCodeBytes = longToByteArray( getMatchingBeaconTypeCode(), mMatchingBeaconTypeCodeEndOffset - mMatchingBeaconTypeCodeStartOffset + 1); if (getServiceUuid() != null) { serviceUuidBytes = longToByteArray( getServiceUuid(), mServiceUuidEndOffset - mServiceUuidStartOffset + 1, false); } startByte = pduToParse.getStartIndex(); boolean patternFound = false; if (getServiceUuid() == null) { if (byteArraysMatch( bytesToProcess, startByte + mMatchingBeaconTypeCodeStartOffset, typeCodeBytes, 0)) { patternFound = true; } } else { if (byteArraysMatch( bytesToProcess, startByte + mServiceUuidStartOffset, serviceUuidBytes, 0) && byteArraysMatch( bytesToProcess, startByte + mMatchingBeaconTypeCodeStartOffset, typeCodeBytes, 0)) { patternFound = true; } } if (patternFound == false) { // This is not a beacon if (getServiceUuid() == null) { if (LogManager.isVerboseLoggingEnabled()) { LogManager.d( TAG, "This is not a matching Beacon advertisement. (Was expecting %s. " + "The bytes I see are: %s", byteArrayToString(typeCodeBytes), bytesToHex(bytesToProcess)); } } else { if (LogManager.isVerboseLoggingEnabled()) { LogManager.d( TAG, "This is not a matching Beacon advertisement. Was expecting %s at offset %d and %s at offset %d. " + "The bytes I see are: %s", byteArrayToString(serviceUuidBytes), startByte + mServiceUuidStartOffset, byteArrayToString(typeCodeBytes), startByte + mMatchingBeaconTypeCodeStartOffset, bytesToHex(bytesToProcess)); } } parseFailed = true; beacon = null; } else { if (LogManager.isVerboseLoggingEnabled()) { LogManager.d( TAG, "This is a recognized beacon advertisement -- %s seen", byteArrayToString(typeCodeBytes)); } } if (patternFound) { if (bytesToProcess.length <= startByte + mLayoutSize && mAllowPduOverflow) { // If the layout size is bigger than this PDU, and we allow overflow. Make sure // the byte buffer is big enough by zero padding the end so we don't try to read // outside the byte array of the advertisement if (LogManager.isVerboseLoggingEnabled()) { LogManager.d( TAG, "Expanding buffer because it is too short to parse: " + bytesToProcess.length + ", needed: " + (startByte + mLayoutSize)); } bytesToProcess = ensureMaxSize(bytesToProcess, startByte + mLayoutSize); } for (int i = 0; i < mIdentifierEndOffsets.size(); i++) { int endIndex = mIdentifierEndOffsets.get(i) + startByte; if (endIndex > pduToParse.getEndIndex() && mIdentifierVariableLengthFlags.get(i)) { if (LogManager.isVerboseLoggingEnabled()) { LogManager.d( TAG, "Need to truncate identifier by " + (endIndex - pduToParse.getEndIndex())); } // If this is a variable length identifier, we truncate it to the size that // is available in the packet Identifier identifier = Identifier.fromBytes( bytesToProcess, mIdentifierStartOffsets.get(i) + startByte, pduToParse.getEndIndex() + 1, mIdentifierLittleEndianFlags.get(i)); identifiers.add(identifier); } else if (endIndex > pduToParse.getEndIndex() && !mAllowPduOverflow) { parseFailed = true; if (LogManager.isVerboseLoggingEnabled()) { LogManager.d( TAG, "Cannot parse identifier " + i + " because PDU is too short. endIndex: " + endIndex + " PDU endIndex: " + pduToParse.getEndIndex()); } } else { Identifier identifier = Identifier.fromBytes( bytesToProcess, mIdentifierStartOffsets.get(i) + startByte, endIndex + 1, mIdentifierLittleEndianFlags.get(i)); identifiers.add(identifier); } } for (int i = 0; i < mDataEndOffsets.size(); i++) { int endIndex = mDataEndOffsets.get(i) + startByte; if (endIndex > pduToParse.getEndIndex() && !mAllowPduOverflow) { if (LogManager.isVerboseLoggingEnabled()) { LogManager.d( TAG, "Cannot parse data field " + i + " because PDU is too short. endIndex: " + endIndex + " PDU endIndex: " + pduToParse.getEndIndex() + ". Setting value to 0"); } dataFields.add(new Long(0l)); } else { String dataString = byteArrayToFormattedString( bytesToProcess, mDataStartOffsets.get(i) + startByte, endIndex, mDataLittleEndianFlags.get(i)); dataFields.add(Long.parseLong(dataString)); } } if (mPowerStartOffset != null) { int endIndex = mPowerEndOffset + startByte; int txPower = 0; try { if (endIndex > pduToParse.getEndIndex() && !mAllowPduOverflow) { parseFailed = true; if (LogManager.isVerboseLoggingEnabled()) { LogManager.d( TAG, "Cannot parse power field because PDU is too short. endIndex: " + endIndex + " PDU endIndex: " + pduToParse.getEndIndex()); } } else { String powerString = byteArrayToFormattedString( bytesToProcess, mPowerStartOffset + startByte, mPowerEndOffset + startByte, false); txPower = Integer.parseInt(powerString) + mDBmCorrection; // make sure it is a signed integer if (txPower > 127) { txPower -= 256; } beacon.mTxPower = txPower; } } catch (NumberFormatException e1) { // keep default value } catch (NullPointerException e2) { // keep default value } } } } if (parseFailed) { beacon = null; } else { int beaconTypeCode = 0; String beaconTypeString = byteArrayToFormattedString( bytesToProcess, mMatchingBeaconTypeCodeStartOffset + startByte, mMatchingBeaconTypeCodeEndOffset + startByte, false); beaconTypeCode = Integer.parseInt(beaconTypeString); // TODO: error handling needed on the parse int manufacturer = 0; String manufacturerString = byteArrayToFormattedString(bytesToProcess, startByte, startByte + 1, true); manufacturer = Integer.parseInt(manufacturerString); String macAddress = null; String name = null; if (device != null) { macAddress = device.getAddress(); name = device.getName(); } beacon.mIdentifiers = identifiers; beacon.mDataFields = dataFields; beacon.mRssi = rssi; beacon.mBeaconTypeCode = beaconTypeCode; if (mServiceUuid != null) { beacon.mServiceUuid = (int) mServiceUuid.longValue(); } else { beacon.mServiceUuid = -1; } beacon.mBluetoothAddress = macAddress; beacon.mBluetoothName = name; beacon.mManufacturer = manufacturer; beacon.mParserIdentifier = mIdentifier; } return beacon; }