Android 传感器返回 null?

huangapple go评论84阅读模式
英文:

Android Sensor return null?

问题

I have translated the code for you. Here's the translated content:

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

        initializeSensors();
        initializeMenu();
    }

    public void initializeSensors() {
        // Sensor initialization code here...
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {
        // Empty method for accuracy changes...
    }

    @Override
    public void onSensorChanged(@NotNull SensorEvent sensorEvent) {
        // Sensor data handling code...
    }

    public void initializeMenu() {
        // Menu initialization code here...
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        // Navigation item selection handling code...
    }

    @Override
    public void onBackPressed() {
        // Back button handling code...
    }
}

Please note that in the provided XML layout code (fragment_acc.xml), there are placeholders like @string/accelerometer which reference string resources. These resources should be defined in your strings.xml resource file.

If you encounter issues with sensorEvent returning null, make sure that the sensors are being properly registered and initialized. The null pointer exception you mentioned could occur if the UI elements (e.g., xAccValue) are not found or initialized correctly, or if the sensor data is not properly updated. Double-check your sensor initialization and data handling logic to identify the cause of the null sensor event.

英文:

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.

答案1

得分: 0

首先,你需要查看错误。

尝试在空对象引用上调用虚拟方法 'void android.widget.TextView.setText(java.lang.CharSequence)'

这意味着你在空对象上调用了方法,而不是使用空参数调用。
因此问题出在 TextView xAccValue,它是空的。

根据我所见,看起来你把 TextView 放在了一个 Fragment 中,这种情况下你需要从 Fragment 的类中引用它(并设置其文本)。

你不能从 MainActivity 中引用 Fragment 中的视图。

英文:

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.

huangapple
  • 本文由 发表于 2020年8月16日 18:06:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/63435550.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定