索尼设备上的传感器数据不稳定

时间:2013-08-08 18:57:54

标签: java android android-sensors sony sensormanager

在过去的几天里,我一直在玩传感器和画布。

到目前为止,我已设法根据设备的角度控制位图的位置。

应用程序的工作方式是获取方向数据,并根据设备的倾斜程度,在屏幕上向左或向右移动位图。

我在运行android 4.2.2(AOKP)的三星Galaxy S II GT-i9100上进行大部分测试,该应用程序运行得非常完美,除了恢复时应用程序崩溃(我想我知道是什么原因造成的)这一点)。

我遇到的问题如下:

当我尝试在Sony Xperia Z上运行相同的代码(运行Android 4.1.2,来自索尼的股票)时,整个应用程序变得不稳定(位图几乎不动),我认为这是因为传感器数据检索不稳定/慢。在我朋友的Sony Xperia S上也是如此。

我把这个应用程序交给了我的另一个有Nexus 4的朋友,他说他没有这样的问题。

GameView

public class GameView extends SurfaceView {

    private Bitmap bmp;
    private SurfaceHolder holder;
    private GameLoopThread gameLoopThread;
    private int x = 0;
    private int xMultiplier = 0;
    private Paint textPaint;

    //lowPass
    private float smoothVal = 0; //Main variable, check algorithm
    private int smoothing = 5; //How strong the smoothing is, larger the value, more time is needed before the value reaches actual sensor value



    //Sensors
    private SensorManager sensorManager;
    private SensorEventListener sensorEventListener;

    //Rotation matrices for converting coordinate systems
    private float[] rotationMatrixR = new float[9];
    private float[] rotationMatrixI = new float[9];

    //Arrays storing data for gravity and geomagnetic data needed to get device's angles
    private float[] gravity = new float[3];
    private float[] geomagnetic = new float[3];

    //Array holding angles
    private float[] angles = new float[3];




    public GameView(Context context) {
        super(context);
        gameLoopThread = new GameLoopThread(this);
        holder = getHolder();
        textPaint = new Paint();
        textPaint.setColor(Color.WHITE);
        textPaint.setTextSize(20);

        sensorManager = (SensorManager)getContext().getSystemService(Context.SENSOR_SERVICE);

        sensorEventListener = new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent sensorEvent) {

                Sensor sensor = sensorEvent.sensor;

                if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                    gravity = sensorEvent.values;
                }
                else if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
                    geomagnetic = sensorEvent.values;
                }

                SensorManager.getRotationMatrix(rotationMatrixR, rotationMatrixI, gravity, geomagnetic);
                SensorManager.getOrientation(rotationMatrixR, angles);
            }

            @Override
            public void onAccuracyChanged(Sensor sensor, int i) {

            }
        };

        sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
        sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_FASTEST);



        holder.addCallback(new SurfaceHolder.Callback() {

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                boolean retry = true;
                gameLoopThread.setRunning(false);

                while (retry) {
                    try {
                        gameLoopThread.join();
                        retry = false;
                    }
                    catch (InterruptedException e) {
                        //Shit hit the fan
                        Log.e("GameLoopThread", e.toString());
                    }
                }
            }

            @Override
            public void surfaceCreated(SurfaceHolder holder){
                gameLoopThread.setRunning(true);
                gameLoopThread.start();
            }
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }
        });
        bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

    }
    @Override
    protected void onDraw(Canvas canvas)
    {

        x = (int) ((canvas.getWidth() / 100) * ((lowPass(angles[2]) * 100) + 50));

        canvas.drawColor(Color.DKGRAY); //This also clears the screen
        canvas.drawBitmap(bmp, x, canvas.getHeight() - bmp.getHeight() - 20, null);

        canvas.drawText("Azimuth (Z): " + Float.toString(angles[0]),25,25, textPaint);
        canvas.drawText("Pitch (X): " + Float.toString(angles[1]),25,45, textPaint);
        canvas.drawText("Roll (Y): " + Float.toString(angles[2]),25,65, textPaint);
        canvas.drawText("X: " + Integer.toString(x),25,85,textPaint);


    }

    public static BigDecimal roundFloat(float d, int decimalPlace) {
        BigDecimal bd = new BigDecimal(Float.toString(d));
        bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
        return bd;
    }

    private float lowPass(float curValue) {
        smoothVal += (curValue - smoothVal) / smoothing;
        return smoothVal;
    }
}

GameLoopThread

public class GameLoopThread extends Thread {
    static final long FPS = 25;
    private GameView view;
    private Boolean running = false;


    public GameLoopThread(GameView view){
        this.view = view;
    }

    public void setRunning(boolean run){
        running = run;
    }

    @Override
    public void run(){
        long tickPS = 1000/FPS;
        long startTime;
        long sleepTime;

        while(running){
            Canvas c = null;
            startTime = System.currentTimeMillis();
            try {
                c = view.getHolder().lockCanvas();
                synchronized (view.getHolder()){
                    view.onDraw(c);
                }
            }

            catch (NullPointerException e) {
                Log.e("GameLoopThread", e.toString());
            }

            finally {
                if (c != null) {
                    view.getHolder().unlockCanvasAndPost(c);
                }
            }

            sleepTime = tickPS - (System.currentTimeMillis() - startTime);

            try {
                if (sleepTime > 0) {
                    sleep(sleepTime);
                }
                else {
                    sleep(10);
                }
            }
            catch (Exception e) {
                Log.e("GameLoopThread", e.toString());
            }

        }
    }
}

0 个答案:

没有答案