I was writing an app to read heart rate and step count using an android wear device. The heart rate sensor works properly but the step count is causing an issue. However, on commenting the listener for Step Counter and registering a null in onResume() the app works with heart rate sensor. I'm not getting any log regarding this otherwise I would have posted it here. Here's the code that I'm using
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.wearable.view.WatchViewStub;
import android.util.Log;
import android.widget.TextView;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;
import java.nio.ByteBuffer;
import java.util.List;
public class MainActivity extends Activity {
private SensorManager mSensorManager;
private TextView mTextViewHeart, mTextViewStep;
private Sensor mHeartRateSensor, mStepCounterSensor;
private GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
mTextViewHeart = (TextView) stub.findViewById(R.id.value_heart);
mTextViewStep = (TextView) stub.findViewById(R.id.value_step);
}
});
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mHeartRateSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);
mStepCounterSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(Wearable.API).build();
mGoogleApiClient.connect();
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(heartListener, mHeartRateSensor, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(stepListener, mStepCounterSensor, SensorManager.SENSOR_DELAY_FASTEST);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(heartListener, mHeartRateSensor);
}
SensorEventListener heartListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_HEART_RATE) {
if (event.values.length > 0) {
if (event.values[0] > 0.0f) {
mTextViewHeart.setBackgroundResource(android.R.color.holo_green_light);
mTextViewHeart.setText(Float.toString(event.values[0]));
sendToHandheld(Math.round(event.values[0]), Sensor.TYPE_HEART_RATE);
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
SensorEventListener stepListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
if (event.values.length > 0) {
mTextViewStep.setBackgroundResource(android.R.color.holo_green_light);
mTextViewStep.setText(Float.toString(event.values[0]));
sendToHandheld(Math.round(event.values[0]), Sensor.TYPE_STEP_COUNTER);
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
private void sendToHandheld(final int val, final int type) {
final PendingResult<NodeApi.GetConnectedNodesResult> nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient);
nodes.setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
@Override
public void onResult(NodeApi.GetConnectedNodesResult result) {
final List<Node> nodes = result.getNodes();
if (nodes != null) {
for (int i = 0; i < nodes.size(); i++) {
final Node node = nodes.get(i);
Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), "/" + type, ByteBuffer.allocate(4).putInt(val).array());
Log.d("Sending", type + ":" + val);
}
}
}
});
}
}
Update
Got the log somehow
06-15 11:46:02.342 3355-3355/com.hsc.fit E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.hsc.fit, PID: 3355
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setBackgroundResource(int)' on a null object reference
at com.hsc.fit.MainActivity$3.onSensorChanged(MainActivity.java:92)
at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:405)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:143)
at android.os.Looper.loop(Looper.java:122)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Fixed it. The
WatchViewStub
'ssetOnLayoutInflatedListener()
is called afteronResume()
, and my Sensor gets registered inonResume()
. Since my text view is used in the listener of the sensor, and it wasn't assigned a refrence yet, I was getting aNullPointerException
. I moved the sensor registertion insideWatchViewStub
's listener and it works now.