sensorManager方法 - 无法恢复活动

时间:2014-01-06 00:49:15

标签: java android android-activity sensormanager

我正在使用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的真正手机有这些传感器并且有了它工作完美无瑕。谢谢你的回答!

1 个答案:

答案 0 :(得分:0)

似乎陀螺传感器列表为空,因此IndexOutOfBoundsException。你能否确认API 16上的仿真器和设备都有陀螺仪?作为安全措施,在尝试从中获取任何元素之前,应检查数组是否为空。