Android Wear Step Counter crashing app

899 Views Asked by At

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)
1

There are 1 best solutions below

0
On BEST ANSWER

Fixed it. The WatchViewStub's setOnLayoutInflatedListener() is called after onResume(), and my Sensor gets registered in onResume(). Since my text view is used in the listener of the sensor, and it wasn't assigned a refrence yet, I was getting a NullPointerException. I moved the sensor registertion inside WatchViewStub's listener and it works now.