Android Sensor return null?

Tags: ,



The Android Java app that I am writing has a simple principle of operation: it reads data from sensors and displays it in a TextView. The first version of the application worked without any problems, but I wanted to improve it and work on the design. I decided to add a slideout side menu and that’s when the problems started. When trying to start in the emulator, an error was thrown that the application was stopped. There was a bug in the logcat (below) above related to TexView that wasn’t there.

MainActivity.java

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, SensorEventListener {


    private static final String TAG = "MainActivity";
    private SensorManager sensorManager;
    private Sensor accelerometer, mGyro, mMagno, mLight, mPressure, mTemp, mHumi;
    TextView xAccValue, yAccValue, zAccValue, xGyroValue, yGyroValue, zGyroValue, xMagnoValue, yMagnoValue, zMagnoValue, light, pressure, temp, humi;

    private DrawerLayout drawer;
    private Object savedInstanceState;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SensorHandler();
        MenuHandler();
    }


    public void SensorHandler() {


        xAccValue = (TextView) findViewById(R.id.AccValueX);
        yAccValue = (TextView) findViewById(R.id.AccValueY);
        zAccValue = (TextView) findViewById(R.id.AccValueZ);

        xGyroValue = (TextView) findViewById(R.id.GyroValueX);
        yGyroValue = (TextView) findViewById(R.id.GyroValueY);
        zGyroValue = (TextView) findViewById(R.id.GyroValueZ);

        xMagnoValue = (TextView) findViewById(R.id.MagnoValueX);
        yMagnoValue = (TextView) findViewById(R.id.MagnoValueY);
        zMagnoValue = (TextView) findViewById(R.id.MagnoValueZ);

        light = (TextView) findViewById(R.id.LightValue);
        pressure = (TextView) findViewById(R.id.PressureValue);
        temp = (TextView) findViewById(R.id.TempSensor);
        humi = (TextView) findViewById(R.id.HumiValue);

        Log.d(TAG, "onCreate: Initializing Sensor Services");
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (accelerometer != null) {

            sensorManager.registerListener(MainActivity.this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
            Log.d(TAG, "onCreate: Registered accelerometer listener");
        } else {
            xAccValue.setText("Accelerometer not supported");
            yAccValue.setText("Accelerometer not supported");
            zAccValue.setText("Accelerometer not supported");
        }

        mGyro = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
        if (mGyro != null) {

            sensorManager.registerListener(MainActivity.this, mGyro, SensorManager.SENSOR_DELAY_NORMAL);
            Log.d(TAG, "onCreate: Registered Gyro listener");
        } else {
            xGyroValue.setText("Gyroscope not supported");
            yGyroValue.setText("Gyroscope not supported");
            zGyroValue.setText("Gyroscope not supported");
        }

        mMagno = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        if (mMagno != null) {

            sensorManager.registerListener(MainActivity.this, mMagno, SensorManager.SENSOR_DELAY_NORMAL);
            Log.d(TAG, "onCreate: Registered Magno listener");
        } else {
            xMagnoValue.setText("Magno not supported");
            yMagnoValue.setText("Magno not supported");
            zMagnoValue.setText("Magno not supported");
        }

        mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
        if (mLight != null) {

            sensorManager.registerListener(MainActivity.this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
            Log.d(TAG, "onCreate: Registered Light listener");
        } else {
            light.setText("Light not supported");
        }

        mPressure = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
        if (mPressure != null) {

            sensorManager.registerListener(MainActivity.this, mPressure, SensorManager.SENSOR_DELAY_NORMAL);
            Log.d(TAG, "onCreate: Registered Pressure listener");
        } else {
            pressure.setText("Pressure not supported");
        }

        mTemp = sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
        if (mTemp != null) {
            sensorManager.registerListener(MainActivity.this, mTemp, SensorManager.SENSOR_DELAY_NORMAL);
            Log.d(TAG, "onCreate: Registered Temp listener");
        } else {
            temp.setText("Pressure not supported");
        }

        mHumi = sensorManager.getDefaultSensor(Sensor.TYPE_RELATIVE_HUMIDITY);
        if (mHumi != null) {
            sensorManager.registerListener(MainActivity.this, mHumi, SensorManager.SENSOR_DELAY_NORMAL);
            Log.d(TAG, "onCreate: Registered Humi listener");
        } else {
            humi.setText("Humi not supported");
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }

    @Override
    public void onSensorChanged(@NotNull SensorEvent sensorEvent) {
        Sensor sensor = sensorEvent.sensor;
        if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            Log.d(TAG, "onSensorChanged: X: " + sensorEvent.values[0] + "Y: " + sensorEvent.values[1] + "Z: " + sensorEvent.values[2]);

            xAccValue.setText("xAccValue: " + sensorEvent.values[0]);
            yAccValue.setText("yAccValue: " + sensorEvent.values[1]);
            zAccValue.setText("zAccValue: " + sensorEvent.values[2]);

        } else if (sensor.getType() == Sensor.TYPE_GYROSCOPE) {
            xGyroValue.setText("xGyroValue: " + sensorEvent.values[0]);
            yGyroValue.setText("yGyroValue: " + sensorEvent.values[1]);
            zGyroValue.setText("zGyroValue: " + sensorEvent.values[2]);

        } else if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            xMagnoValue.setText("xMagnoValue: " + sensorEvent.values[0]);
            yMagnoValue.setText("yMagnoValue: " + sensorEvent.values[1]);
            zMagnoValue.setText("zMagnoValue: " + sensorEvent.values[2]);
        } else if (sensor.getType() == Sensor.TYPE_LIGHT) {
            light.setText("Light: " + sensorEvent.values[0]);
        } else if (sensor.getType() == Sensor.TYPE_PRESSURE) {
            pressure.setText("Pressure: " + sensorEvent.values[0]);
        } else if (sensor.getType() == Sensor.TYPE_AMBIENT_TEMPERATURE) {
            temp.setText("Temp: " + sensorEvent.values[0]);
        } else if (sensor.getType() == Sensor.TYPE_RELATIVE_HUMIDITY) {
            humi.setText("Humi: " + sensorEvent.values[0]);
        }
    }

    public void MenuHandler() {
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        if (savedInstanceState == null) {

            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AccFragment()).commit();
            navigationView.setCheckedItem(R.id.nav_view);
        }
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        switch (menuItem.getItemId()) {
            case R.id.nav_acc:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AccFragment()).commit();
                break;
            case R.id.nav_gyro:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new GyroFragment()).commit();
                break;
            case R.id.nav_magno:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MagnoFragment()).commit();
                break;
            case R.id.nav_light:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new LightFragment()).commit();
                break;
            case R.id.nav_pressure:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new PressureFragment()).commit();
                break;
            case R.id.nav_temp:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new TempFragment()).commit();
                break;
            case R.id.nav_humi:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new HumiFragment()).commit();
                break;
        }

        drawer.closeDrawer(GravityCompat.START);

        return true;
    }

    @Override
    public void onBackPressed() {
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }

    }

}

fragment_acc.xml where I try pass value

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffe135">



        <TextView
            android:id="@+id/AccValueX"
            android:layout_width="200sp"
            android:layout_height="wrap_content"
            android:text="@string/accelerometer"
            android:layout_centerHorizontal="true"
            android:textSize="30sp" />

        <TextView
            android:id="@+id/AccValueY"
            android:layout_width="200sp"
            android:layout_height="wrap_content"
            android:layout_below="@id/AccValueX"
            android:text="@string/accelerometer"
            android:layout_centerInParent="true"
            android:textSize="30sp" />

        <TextView
            android:id="@+id/AccValueZ"
            android:layout_width="200sp"
            android:layout_height="wrap_content"
            android:layout_below="@id/AccValueY"
            android:text="@string/accelerometer"
            android:layout_centerInParent="true"
            android:textSize="30sp" />


</RelativeLayout>

LogCat Error

2020-08-16 11:13:54.853 24668-24668/com.example.sensapp_v11 E/SensorManager: Exception dispatching input event.
2020-08-16 11:13:54.854 24668-24668/com.example.sensapp_v11 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.sensapp_v11, PID: 24668
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
        at com.example.sensapp_v11.MainActivity.onSensorChanged(MainActivity.java:155)
        at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:699)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:323)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

I see this is the problem in line 155:

    xAccValue.setText("xAccValue: " + sensorEvent.values[0]);

It seems sensorEvent return null. The question is why? The first version of the app without additional fragments work perfectly.

Answer

First, you need to look at the error.

attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

It means that you called the method ON a null thing, not WITH a null parameter. Therefore the problem is the TextView xAccValue, which is null.

From what I’ve seen, it looks like you put the TextView in a Fragment, in that case you need to reference (and set its text) from the Fragment‘s class.

You cannot reference Views in your Fragment from MainActivity.



Source: stackoverflow