protected static Beacon beaconFromScanResult(ScanResult scanResult) { ScanRecord scanRecord = scanResult.getScanRecord(); if (scanRecord == null) { return null; } FrameType type; Integer txPower; double rssi = scanResult.getRssi(); byte[] bytes = scanRecord.getServiceData(EDDYSTONE_SPEC); String identifier = scanResult.getDevice().getAddress(); txPower = txPowerFromBytes(bytes); if (txPower != null) { Beacon beacon = new Beacon(rssi, txPower, identifier); beacon.parseScanResult(scanResult); return beacon; } return null; }
private void processResult(ScanResult result) { ScanRecord record = result.getScanRecord(); if (record == null || record.getServiceData(UID_SERVICE) == null) { Log.w(TAG, "Invalid Eddystone scan result."); return; } //Convert scan result into an AdvertisedId Beacon.AdvertisedId advertisedId = Beacon.AdvertisedId.fromAdvertisement(record.getServiceData(UID_SERVICE)); final Beacon discovered = new Beacon(advertisedId, Beacon.Status.STATUS_UNSPECIFIED); //Scan callbacks are not on the main thread runOnUiThread(new Runnable() { @Override public void run() { //Notify the adapter, and get beacon resource from API boolean added = mAdapter.addDiscoveredBeacon(discovered); if (added) { mProximityApi.getBeacon(discovered.advertisedId); } } }); }
/** * Callback when a BLE advertisement has been found. * * @param callbackType Determines how this callback was triggered. * @param result A Bluetooth LE scan result. */ @Override public void onScanResult(int callbackType, final ScanResult result) { super.onScanResult(callbackType, result); // Get the ScanRecord and check if it is defined (is nullable) final ScanRecord scanRecord = result.getScanRecord(); if (scanRecord != null) { // Check if the Service UUIDs are defined (is nullable) and contain the discovery // UUID final List<ParcelUuid> serviceUuids = scanRecord.getServiceUuids(); if (serviceUuids != null && serviceUuids.contains(DISCOVERY_UUID)) { // We have found our device, so update the GUI, stop scanning and start // connecting final BluetoothDevice device = result.getDevice(); // We'll make sure the GUI is updated on the UI thread runOnUiThread(new Runnable() { @Override public void run() { // At this point we have the device address and RSSI, so update those deviceAddressTextView.setText(device.getAddress()); rssiTextView.setText(getString(R.string.rssi, result.getRssi())); } }); stopDiscovery(); bluetoothGatt = device.connectGatt( MainActivity.this, // False here, as we want to directly connect to the device false, bluetoothGattCallback ); } } }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) ScanRecordCompat(ScanRecord record) { mServiceUuids = record.getServiceUuids(); mManufacturerSpecificData = record.getManufacturerSpecificData(); mServiceData = record.getServiceData(); mDeviceName = record.getDeviceName(); mAdvertiseFlags = record.getAdvertiseFlags(); mTxPowerLevel = record.getTxPowerLevel(); mBytes = record.getBytes(); }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) public BleDevice convertBleDevice(ScanResult scanResult) { if (scanResult == null) { throw new IllegalArgumentException("scanResult can not be Null!"); } BluetoothDevice bluetoothDevice = scanResult.getDevice(); int rssi = scanResult.getRssi(); ScanRecord scanRecord = scanResult.getScanRecord(); byte[] bytes = null; if (scanRecord != null) bytes = scanRecord.getBytes(); long timestampNanos = scanResult.getTimestampNanos(); return new BleDevice(bluetoothDevice, rssi, bytes, timestampNanos); }
private void initScanData() { scanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); Log.i(TAG, "onScanResult" + result); String address = result.getDevice().getAddress(); String name; ScanRecord scanRecord = result.getScanRecord(); name = scanRecord == null ? "unknown" : scanRecord.getDeviceName(); scanResultListener.onResultReceived(name, address); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); Log.e(TAG, "onBatchScanResults"); } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); Log.e(TAG, "onScanFailed"); scanResultListener.onScanFailed(errorCode); } }; filters = new ArrayList<>(); filters.add(new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString(BLEProfile.UUID_SERVICE)).build()); scanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) public TemperatureBeacon(ScanRecord record, String deviceAddress, int rssi) { mSignal = rssi; mAddress = deviceAddress; mName = record.getDeviceName(); byte[] data = record.getServiceData(THERM_SERVICE); if (data != null) { mCurrentTemp = parseTemp(data); } else { mCurrentTemp = 0f; } }
public static ScanRecord parseScanRecordFromBytes(byte[] bytes) { try { Method parseFromBytes = ScanRecord.class.getMethod("parseFromBytes", byte[].class); return (ScanRecord) parseFromBytes.invoke(null, (Object) bytes); } catch (Exception e) { throw new RuntimeException(e); } }
private void processResult(ScanResult result) { ScanRecord record = result.getScanRecord(); if (record == null) { Log.w(TAG, "Invalid scan record."); return; } final byte[] data = record.getServiceData(UID_SERVICE); if (data == null) { Log.w(TAG, "Invalid Eddystone scan result."); return; } final String deviceAddress = result.getDevice().getAddress(); final int rssi = result.getRssi(); byte frameType = data[0]; switch (frameType) { case TYPE_UID: mCallbackHandler.post(new Runnable() { @Override public void run() { processUidPacket(deviceAddress, rssi, data); } }); break; case TYPE_TLM: case TYPE_URL: //Do nothing, ignoring these return; default: Log.w(TAG, "Invalid Eddystone scan result."); } }
@Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); ScanRecord record = result.getScanRecord(); if(record!=null) mCallbackPre21.onLeScan(result.getDevice(),result.getRssi(),record.getBytes()); }
public BLEScanner(final Activity activity, int requestEnableBluetooth, @NonNull OnClosestChangedListener onClosestChangedListener) { mRequestEnableBluetooth = requestEnableBluetooth; mOnClosestChangedListener = onClosestChangedListener; init(activity); scanFilters = new ArrayList<>(); scanFilters.add(new ScanFilter.Builder().setServiceUuid(EDDYSTONE_SERVICE_UUID).build()); scanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { ScanRecord scanRecord = result.getScanRecord(); if (scanRecord == null) { return; } String deviceAddress = result.getDevice().getAddress(); Beacon beacon; if (!deviceToBeaconMap.containsKey(deviceAddress)) { beacon = new Beacon(deviceAddress, result.getRssi()); deviceToBeaconMap.put(deviceAddress, beacon); } else { deviceToBeaconMap.get(deviceAddress).lastSeenTimestamp = System.currentTimeMillis(); deviceToBeaconMap.get(deviceAddress).rssi = result.getRssi(); } byte[] serviceData = scanRecord.getServiceData(EDDYSTONE_SERVICE_UUID); validateServiceData(deviceAddress, serviceData); findClosest(); } @Override public void onScanFailed(int errorCode) { switch (errorCode) { case SCAN_FAILED_ALREADY_STARTED: logErrorAndShowToast(activity, "SCAN_FAILED_ALREADY_STARTED"); break; case SCAN_FAILED_APPLICATION_REGISTRATION_FAILED: logErrorAndShowToast(activity, "SCAN_FAILED_APPLICATION_REGISTRATION_FAILED"); break; case SCAN_FAILED_FEATURE_UNSUPPORTED: logErrorAndShowToast(activity, "SCAN_FAILED_FEATURE_UNSUPPORTED"); break; case SCAN_FAILED_INTERNAL_ERROR: logErrorAndShowToast(activity, "SCAN_FAILED_INTERNAL_ERROR"); break; default: logErrorAndShowToast(activity, "Scan failed, unknown error code"); break; } } }; }
public void scanPeripheralWithServicesUUID_API21(final String uuid) { if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { requestOpenBT(); return; } BluetoothLeScanner scanner = mBluetoothAdapter.getBluetoothLeScanner(); ScanSettings settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); List<ScanFilter> list = new ArrayList<ScanFilter>(1); ScanCallback callback = new ScanCallback() { @Override public void onScanResult(int callbackType, android.bluetooth.le.ScanResult result) { BluetoothDevice device = result.getDevice(); ScanRecord sr = result.getScanRecord(); int rssi = result.getRssi(); // if (rssi > -15) { // runCallbackWithErrorCode(BLEUtilErrorCode.E_RSSI_ERROR); // return; // } // if (rssi < -35) { // runCallbackWithErrorCode(BLEUtilErrorCode.E_RSSI_TOO_LOW); // return; // } if (matchRules(rssi, sr.getBytes(), uuid)) { connectToDevice(device); } } @Override public void onScanFailed(int errorCode) { } }; if (uuid != null) { ScanFilter filter = new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString(uuid)).build(); list.add(filter); scanner.startScan(list, settings, callback); } else { // scanner.startScan(null, settings, callback); scanner.startScan(callback); } }
private void initScanData() { scanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); Log.d(TAG, "["+ Thread.currentThread().getStackTrace()[2].getFileName() + "_" + Thread.currentThread().getStackTrace()[2].getLineNumber() + "_" + Thread.currentThread().getStackTrace()[2].getMethodName() + "]"); Log.i(TAG, "result" + result); String address = result.getDevice().getAddress(); String name; ScanRecord scanRecord = result.getScanRecord(); int mRssi = result == null ? -127: result.getRssi(); Log.i(TAG, "Rssi: " +mRssi); name = scanRecord == null ? "unknown" : scanRecord.getDeviceName(); //TODO stop scan // if (name != null) // { // Log.d(TAG, "["+ // Thread.currentThread().getStackTrace()[2].getFileName() + "_" + // Thread.currentThread().getStackTrace()[2].getLineNumber() + "_" + // Thread.currentThread().getStackTrace()[2].getMethodName() + "]" + "========StopScan"); // stopScan(); // } scanResultListener.onResultReceived(name, address, mRssi); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); Log.d(TAG, "["+ Thread.currentThread().getStackTrace()[2].getFileName() + "_" + Thread.currentThread().getStackTrace()[2].getLineNumber() + "_" + Thread.currentThread().getStackTrace()[2].getMethodName() + "]"); Log.e(TAG, "onBatchScanResults"); } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); Log.d(TAG, "["+ Thread.currentThread().getStackTrace()[2].getFileName() + "_" + Thread.currentThread().getStackTrace()[2].getLineNumber() + "_" + Thread.currentThread().getStackTrace()[2].getMethodName() + "]"); Log.e(TAG, "onScanFailed"); scanResultListener.onScanFailed(errorCode); } }; filters = new ArrayList<>(); filters.add(new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString(BLEProfile.UUID_SERVICE)).build()); scanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); }
private void handleScanResult ( ScanResult scanResult) { BluetoothDevice aBluetoothDevice = scanResult.getDevice() ; Log.d (TAG, "handleScanResult aBluetoothDevice =" + aBluetoothDevice.toString()) ; foundBluetoothDevices.put(aBluetoothDevice.getAddress(), aBluetoothDevice) ; refreshView(foundBluetoothDevices); aBluetoothDevice.getName() ; aBluetoothDevice.getAddress() ; aBluetoothDevice.getBluetoothClass() ; ScanRecord aScanRecord = scanResult.getScanRecord() ; int signalStrengthDbm = scanResult.getRssi() ; // signal strength in dBm. //dBmW or Decibel-milliwatts), power ratio in decibels (dB) of the measured power // referenced to one milliwatt (mW) scanResult.getTimestampNanos() ; }
protected void parseScanResult(ScanResult scanResult) { ScanRecord scanRecord = scanResult.getScanRecord(); if (scanRecord == null) { return; } double rssi = scanResult.getRssi(); byte[] bytes = scanRecord.getServiceData(EDDYSTONE_SPEC); updateRssi(rssi); FrameType type = frameTypeFromBytes(bytes); if (type != null) { switch (type) { case URL: UrlFrame urlFrame = UrlFrame.frameWithBytes(bytes); if (urlFrame != null) { mFrames[0] = urlFrame; Global.log("Parsed URL Frame with mUrl: " + urlFrame.mUrl); notifyChange(); } break; case UID: UidFrame uidFrame = UidFrame.frameWithBytes(bytes); if (uidFrame != null) { mFrames[1] = uidFrame; Global.log("Parsed UID Frame with uid: " + uidFrame.getUid()); notifyChange(); } break; case TLM: TlmFrame tlmFrame = TlmFrame.frameWithBytes(bytes); if (tlmFrame != null) { mFrames[2] = tlmFrame; Global.log("Parsed TLM Frame with battery: " + tlmFrame.mBatteryVolts + " temperature: " + tlmFrame.mTemperature + " advertisement count: " + tlmFrame.mAdvertisementCount + " on time: " + tlmFrame.mOnTime); notifyChange(); } break; default: break; } } }
@Override public boolean onStartJob(final JobParameters jobParameters) { initialzeScanHelper(); if (jobParameters.getJobId() == IMMEDIATE_SCAN_JOB_ID) { LogManager.i(TAG, "Running immediate scan job: instance is "+this); } else { LogManager.i(TAG, "Running periodic scan job: instance is "+this); } List<ScanResult> queuedScanResults = ScanJobScheduler.getInstance().dumpBackgroundScanResultQueue(); LogManager.d(TAG, "Processing %d queued scan resuilts", queuedScanResults.size()); for (ScanResult result : queuedScanResults) { ScanRecord scanRecord = result.getScanRecord(); if (scanRecord != null) { mScanHelper.processScanResult(result.getDevice(), result.getRssi(), scanRecord.getBytes()); } } LogManager.d(TAG, "Done processing queued scan resuilts"); boolean startedScan; if (mInitialized) { LogManager.d(TAG, "Scanning already started. Resetting for current parameters"); startedScan = restartScanning(); } else { startedScan = startScanning(); } mStopHandler.removeCallbacksAndMessages(null); if (startedScan) { LogManager.i(TAG, "Scan job running for "+mScanState.getScanJobRuntimeMillis()+" millis"); mStopHandler.postDelayed(new Runnable() { @Override public void run() { LogManager.i(TAG, "Scan job runtime expired: " + ScanJob.this); stopScanning(); mScanState.save(); ScanJob.this.jobFinished(jobParameters , false); // need to execute this after the current block or Android stops this job prematurely mStopHandler.post(new Runnable() { @Override public void run() { scheduleNextScan(); } }); } }, mScanState.getScanJobRuntimeMillis()); } else { LogManager.i(TAG, "Scanning not started so Scan job is complete."); ScanJob.this.jobFinished(jobParameters , false); } return true; }
/** * Serialize ScanRecord for Bluetooth LE. * * <p>Not all fields are serialized here. Will add more as we need. * * <pre>The returned {@link Bundle} has the following info: * "DeviceName", String * "TxPowerLevel", String * </pre> * * @param record A {@link ScanRecord} object. * @return A {@link Bundle} object. */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) private Bundle serializeBleScanRecord(ScanRecord record) { Bundle result = new Bundle(); result.putString("DeviceName", record.getDeviceName()); result.putInt("TxPowerLevel", record.getTxPowerLevel()); return result; }