我正在使用Android手机编写一个简单的IMU(通过TCP将数据发送到计算机并在PC上可视化)。问题是代码编译和在API 18和19上完美运行(在不同的手机上查看),问题是它不想在API 16上工作 (电话和模拟器)。我设法注意到问题在于初始化传感器的方法。我在下面发布了一个代码和一个logcat错误。我已经削减了对SD的写入并通过TCP发送,因为它可以完美地在API 16上工作(当initSensors();被注释掉时)。希望您能够帮助我。罗伯特
主要课程:
public class Sensor412 extends Activity {
public SensorManager mSensorManager;
public mySensors mSensors;
// Initializing Sensors
void initSensors() {
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
List<Sensor> accel_sensor_list = mSensorManager
.getSensorList(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener((SensorEventListener) mSensors,
accel_sensor_list.get(0), SensorManager.SENSOR_DELAY_UI);
List<Sensor> magn_sensor_list = mSensorManager
.getSensorList(Sensor.TYPE_MAGNETIC_FIELD);
mSensorManager.registerListener((SensorEventListener) mSensors,
magn_sensor_list.get(0), SensorManager.SENSOR_DELAY_UI);
List<Sensor> gyro_sensor_list = mSensorManager
.getSensorList(Sensor.TYPE_GYROSCOPE);
mSensorManager.registerListener((SensorEventListener) mSensors,
gyro_sensor_list.get(0), SensorManager.SENSOR_DELAY_UI);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Creating sensor class
mSensors = new mySensors();
}//onCreate
@Override
protected void onPause() {
super.onPause();
// Wyłącz odczyt gdy aplikacja wchodzi w stan Pause
mSensorManager.unregisterListener(mSensors);
}//onPause
@Override
protected void onResume() {
super.onResume();
// Włącz odczyt gdy aplikacja zostanie wznowiona (stan Resume)
initSensors();
}//onResume
}
mySensors类:
package com.example.sensor412;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
public class mySensors implements SensorEventListener {
private static int VECTOR_SIZE = 3;
private static int MATRIX_SIZE = 16;
private int type;
public static float z_deg, y_deg, x_deg, accels_x, accels_y, accels_z,
magn_x, magn_y, magn_z, gyro_x, gyro_y, gyro_z;
private boolean isReady;
float[] vals = new float[VECTOR_SIZE];
float[] accels = new float[VECTOR_SIZE];
float[] magn = new float[VECTOR_SIZE];
float[] gyro = new float[VECTOR_SIZE];
float[] orientation_rad = new float[VECTOR_SIZE];
float[] R_orig = new float[MATRIX_SIZE];
float[] I_orig = new float[VECTOR_SIZE];
float[] R_remapped = new float[MATRIX_SIZE];
public void onSensorChanged(SensorEvent event) {
type = event.sensor.getType();
vals = event.values.clone();
switch (type) {
case Sensor.TYPE_ACCELEROMETER:
accels = vals.clone();
break;
case Sensor.TYPE_MAGNETIC_FIELD:
magn = vals.clone();
break;
case Sensor.TYPE_GYROSCOPE:
gyro = vals.clone();
isReady = true;
}
if (isReady && magn != null && accels != null && gyro != null) {
isReady = false;
SensorManager.getRotationMatrix(R_orig, I_orig, accels, magn);
SensorManager.getOrientation(R_orig, orientation_rad);
//rad->deg
z_deg = orientation_rad[0] * 57.2957795f;
y_deg = orientation_rad[1] * 57.2957795f;
x_deg = orientation_rad[2] * 57.2957795f;
accels_x = accels[0];
accels_y = accels[1];
accels_z = accels[2];
magn_x = magn[0];
magn_y = magn[1];
magn_z = magn[2];
gyro_x = gyro[0];
gyro_y = gyro[1];
gyro_z = gyro[2];
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
}
Logcat错误:
01-06 00:10:16.296: E/AndroidRuntime(660): java.lang.RuntimeException: Unable to resume activity {com.example.sensor412/com.example.sensor412.Sensor412}: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
01-06 00:10:16.296: E/AndroidRuntime(660): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2575)
01-06 00:10:16.296: E/AndroidRuntime(660): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2603)
01-06 00:10:16.296: E/AndroidRuntime(660): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2089)
01-06 00:10:16.296: E/AndroidRuntime(660): at android.app.ActivityThread.access$600(ActivityThread.java:130)
01-06 00:10:16.296: E/AndroidRuntime(660): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
01-06 00:10:16.296: E/AndroidRuntime(660): at android.os.Handler.dispatchMessage(Handler.java:99)
01-06 00:10:16.296: E/AndroidRuntime(660): at android.os.Looper.loop(Looper.java:137)
01-06 00:10:16.296: E/AndroidRuntime(660): at android.app.ActivityThread.main(ActivityThread.java:4745)
01-06 00:10:16.296: E/AndroidRuntime(660): at java.lang.reflect.Method.invokeNative(Native Method)
01-06 00:10:16.296: E/AndroidRuntime(660): at java.lang.reflect.Method.invoke(Method.java:511)
01-06 00:10:16.296: E/AndroidRuntime(660): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-06 00:10:16.296: E/AndroidRuntime(660): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-06 00:10:16.296: E/AndroidRuntime(660): at dalvik.system.NativeStart.main(Native Method)
01-06 00:10:16.296: E/AndroidRuntime(660): Caused by: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
01-06 00:10:16.296: E/AndroidRuntime(660): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
01-06 00:10:16.296: E/AndroidRuntime(660): at java.util.ArrayList.get(ArrayList.java:304)
01-06 00:10:16.296: E/AndroidRuntime(660): at java.util.Collections$UnmodifiableList.get(Collections.java:1050)
01-06 00:10:16.296: E/AndroidRuntime(660): at com.example.sensor412.Sensor412.initSensors(Sensor412.java:125)
01-06 00:10:16.296: E/AndroidRuntime(660): at com.example.sensor412.Sensor412.onResume(Sensor412.java:266)
01-06 00:10:16.296: E/AndroidRuntime(660): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1184)
01-06 00:10:16.296: E/AndroidRuntime(660): at android.app.Activity.performResume(Activity.java:5082)
01-06 00:10:16.296: E/AndroidRuntime(660): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2565)
01-06 00:10:16.296: E/AndroidRuntime(660): ... 12 more
我想再次在Android 4.3和4.4上添加它确实可以正常工作 - 作为证据,我在运行Android 4.4的Nexus 4中添加了截图。 (https://dl.dropboxusercontent.com/u/60262901/sensorapp.png)
编辑:感谢您的答案,因为我正在测试应用程序的手机而且没有陀螺仪它会导致问题,API 18和19的真正手机有这些传感器并且有了它工作完美无瑕。谢谢你的回答!
答案 0 :(得分:0)
似乎陀螺传感器列表为空,因此IndexOutOfBoundsException
。你能否确认API 16上的仿真器和设备都有陀螺仪?作为安全措施,在尝试从中获取任何元素之前,应检查数组是否为空。