Note that there are some explanatory texts on larger screens.

plurals
  1. POSensor data choppy on Sony devices
    primarykey
    data
    text
    <p>For the past few days I've been playing around with sensors and canvas.</p> <p>So far I've managed to control the location of a bitmap based on device's angles.</p> <p>The way app works is it gets orientation data, and depending on how much the device is tilted, it moves the bitmap left or right on the screen.</p> <p>I do most of my testing on my Samsung Galaxy S II GT-i9100 running android 4.2.2 (AOKP), and the app works pretty much flawlessly, apart from the app crashing when resuming it (I think I know what's causing that).</p> <p>The problem I'm having is as follows:</p> <p>When I try running the same code on a Sony Xperia Z (running android 4.1.2, stock from Sony) the whole app becomes choppy (the bitmap barely moves), and I think it's because the sensor data retrieval is choppy/slow. Same happens on my friend's Sony Xperia S.</p> <p>I gave the app to my other friend who has a Nexus 4, he says he has no such problems.</p> <p><strong>GameView</strong></p> <pre><code>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; } } </code></pre> <p><strong>GameLoopThread</strong></p> <pre><code>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 &gt; 0) { sleep(sleepTime); } else { sleep(10); } } catch (Exception e) { Log.e("GameLoopThread", e.toString()); } } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload