0

我正在使用 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    
    }

我的传感器类:

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

    }
}

日志错误:

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 的真实手机具有这些传感器并且它完美地工作。感谢您的回答!

4

1 回答 1

0

陀螺仪传感器列表看起来好像是空的,因此IndexOutOfBoundsException. 你能确认 API 16 上的模拟器和设备都有陀螺仪吗?作为安全措施,您应该在尝试从中获取任何元素之前检查该数组是否为空。

于 2014-01-06T01:27:13.990 回答