The error message I see is:
Attempt to invoke virtual method 'void android.bluetooth.le.BluetoothLeScanner.startScan(java.util.List, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback)' on a null object reference at com.example.drodo.diamondbeacons.BleDevicesActivity.startScanning(BleDevicesActivity.java:91) at com.example.drodo.diamondbeacons.BleDevicesActivity$1.onClick(BleDevicesActivity.java:68). Error in line: mBluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), mScanCallback);
Here's my code:
public class BleDevicesActivity extends AppCompatActivity {
private Toolbar bleToolbar;
private static final String TAG = BleDevicesActivity.class.getName();
private static final long SCAN_PERIOD = 5000;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mBluetoothLeScanner;
private ScanCallback mScanCallback;
private TextView deviceName;
private TextView deviceAddress;
private Button scanDevicesBtn;
private Handler mHandler;
public void setBluetoothAdapter(BluetoothAdapter btAdapter) {
this.mBluetoothAdapter = btAdapter;
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ble_devices);
mHandler = new Handler();
bleToolbar = (Toolbar) findViewById(R.id.ble_toolbar);
setSupportActionBar(bleToolbar);
getSupportActionBar().setTitle("Ble Devices Nearby");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
deviceName = (TextView) findViewById(R.id.device_name_text);
deviceAddress = (TextView) findViewById(R.id.device_address_text);
scanDevicesBtn = (Button) findViewById(R.id.scan_devices_btn);
scanDevicesBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startScanning();
Snackbar.make(v, "Scanning for BLE Devices Nearby", Snackbar.LENGTH_SHORT)
.setAction("Action", null).show();
}
});
}
public void startScanning() {
if (mScanCallback == null) {
Log.d(TAG, "Starting Scanning");
// Will stop the scanning after a set time.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
stopScanning();
Toast.makeText(BleDevicesActivity.this, "Scanning Stopped", Toast.LENGTH_SHORT).show();
}
}, SCAN_PERIOD);
// Kick off a new scan.
mScanCallback = new SampleScanCallback();
mBluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), mScanCallback);
String toastText = getString(R.string.scan_start_toast) + " "
+ TimeUnit.SECONDS.convert(SCAN_PERIOD, TimeUnit.MILLISECONDS) + " "
+ getString(R.string.seconds);
Toast.makeText(BleDevicesActivity.this, toastText, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(BleDevicesActivity.this, R.string.already_scanning, Toast.LENGTH_SHORT).show();
}
}
/**
* Stop scanning for BLE Advertisements.
*/
public void stopScanning() {
Log.d(TAG, "Stopping Scanning");
// Stop the scan, wipe the callback.
mBluetoothLeScanner.stopScan(mScanCallback);
mScanCallback = null;
// Even if no new results, update 'last seen' times.
//amAdapter.notifyDataSetChanged();
}
/**
* Return a List of {@link ScanFilter} objects to filter by Service UUID.
*/
private List<ScanFilter> buildScanFilters() {
List<ScanFilter> scanFilters = new ArrayList<>();
ScanFilter.Builder builder = new ScanFilter.Builder();
builder.setServiceUuid(BleConstants.Service_UUID);
scanFilters.add(builder.build());
return scanFilters;
}
/**
* Return a {@link ScanSettings} object set to use low power (to preserve battery life).
*/
private ScanSettings buildScanSettings() {
ScanSettings.Builder builder = new ScanSettings.Builder();
builder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
return builder.build();
}
/**
* Custom ScanCallback object - adds to adapter on success, displays error on failure.
*/
private class SampleScanCallback extends ScanCallback {
@Override
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
for (ScanResult result : results) {
String device_name = result.getDevice().getName();
String device_address = result.getDevice().getAddress();
deviceName.setText(device_name);
deviceAddress.setText(device_address);
}
}
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
try {
ScanRecord scanRecord = result.getScanRecord();
assert scanRecord != null;
byte[] manufacturerData = scanRecord.getManufacturerSpecificData(0x0590);
assert manufacturerData != null;
double lightValue = Double.parseDouble(Arrays.toString(new byte[]{manufacturerData[0]}).replace("[", "").replace("]", ""));
double tempValue = Double.parseDouble(Arrays.toString(new byte[]{manufacturerData[1]}).replace("[", "").replace("]", ""));
double batteryValue = Integer.parseInt(Arrays.toString(new byte[]{manufacturerData[2]}).replace("[", "").replace("]", ""));
int alertPresses = Integer.parseInt(Arrays.toString(new byte[]{manufacturerData[3]}).replace("[", "").replace("]", ""));
Toast.makeText(BleDevicesActivity.this, "LIGHT: " + lightValue + " %", Toast.LENGTH_SHORT).show();
Toast.makeText(BleDevicesActivity.this, "TEMPERATURE: " + tempValue + " \u2103", Toast.LENGTH_SHORT).show();
Toast.makeText(BleDevicesActivity.this, "BATTERY LEVEL: " + batteryValue + " Volts", Toast.LENGTH_SHORT).show();
Toast.makeText(BleDevicesActivity.this, "ALERT PRESSES: " + alertPresses, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
String error_message = e.getMessage();
Toast.makeText(BleDevicesActivity.this, "Error: " + error_message, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
Toast.makeText(BleDevicesActivity.this, "Scan failed with error: " + errorCode, Toast.LENGTH_LONG)
.show();
}
}
}
What could be causing the crash?