英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论