MetaMotionR reading battery level causes NPE
Hello. I read device battery level every 0.5 seconds asynchronously using ScheduledExecutorService. It works fine most of the time but rarely causes a NullPointerException thrown from mbientlab api library. Here's my code:
Created subscriber
private Subscriber chargeHandler = (Subscriber) (data, env) -> {
Settings.BatteryState batteryState = data.value(Settings.BatteryState.class);
charge = batteryState.charge;
};
When connecting
Settings boardSettings = metaWearBoard.getModule(Settings.class);
if (boardSettings == null) {
return null;
}
boardSettings.editBleConnParams()
.maxConnectionInterval(11.25f)
.commit();
settingsCapture.set(boardSettings);
return boardSettings.battery()
.addRouteAsync(source -> source.stream(chargeHandler));
Then every 0.5 seconds I do
settingsCapture.get().battery().read();
Stack trace:
java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.mbientlab.metawear.android.BtleService$GattOp.msg' on a null object reference
at com.mbientlab.metawear.android.BtleService.executeGattOperation(BtleService.java:108)
at com.mbientlab.metawear.android.BtleService.addGattOperation(BtleService.java:101)
at com.mbientlab.metawear.android.BtleService.access$600(BtleService.java:76)
at com.mbientlab.metawear.android.BtleService$AndroidPlatform.writeCharacteristicAsync(BtleService.java:357)
at com.mbientlab.metawear.impl.JseMetaWearBoard$1.sendCommand(JseMetaWearBoard.java:185)
at com.mbientlab.metawear.impl.DataTypeBase.read(DataTypeBase.java:154)
at com.mbientlab.metawear.impl.SettingsImpl$3.read(SettingsImpl.java:397)
at com.solut.metaweardongles.device.DeviceState.readBatteryLevel(DeviceState.java:242)
at com.solut.metaweardongles.device.DeviceManager$$Lambda$6.accept(Unknown Source)
at java.util.HashMap$Values.forEach(HashMap.java:1268)
at com.solut.metaweardongles.device.DeviceManager.updateDevicesState(DeviceManager.java:288)
at com.solut.metaweardongles.device.DeviceManager.bridge$lambda$0$DeviceManager(DeviceManager.java)
at com.solut.metaweardongles.device.DeviceManager$$Lambda$5.run(Unknown Source)
at com.solut.metaweardongles.utils.ExecutorHelper$ExceptionLoggingRunnable.run(ExecutorHelper.java:25)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:278)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:273)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:760)
This discussion has been closed.
Comments
I'll have to look into the NPE more. Regardless, use the Timer class to schedule period reads, especially if you are doing them that frequently:
https://mbientlab.com/androiddocs/3/timer.html