diff options
author | Samuel Tardieu <sam@rfc1149.net> | 2015-08-31 13:33:57 +0200 |
---|---|---|
committer | Samuel Tardieu <sam@rfc1149.net> | 2015-08-31 13:33:57 +0200 |
commit | 54c2a6c2ea1ca8440ea8ba3bd838d340509aa2f6 (patch) | |
tree | 5fb52332d284bd3ca9acfe7f74a4bc19efa87430 | |
parent | 554a4e8b87f187dba55450c57f6a1ae783e12e19 (diff) | |
download | cgeo-54c2a6c2ea1ca8440ea8ba3bd838d340509aa2f6.zip cgeo-54c2a6c2ea1ca8440ea8ba3bd838d340509aa2f6.tar.gz cgeo-54c2a6c2ea1ca8440ea8ba3bd838d340509aa2f6.tar.bz2 |
Apply the workaround for Samsung devices only when strictly needed
Since Samsung firmware may have been fixed and accept more than 4 values
in getRotationMatrixFromVector(), truncate the size of the rotation
vector only when this is strictly needed.
-rw-r--r-- | main/src/cgeo/geocaching/sensors/RotationProvider.java | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/main/src/cgeo/geocaching/sensors/RotationProvider.java b/main/src/cgeo/geocaching/sensors/RotationProvider.java index 59be8f1..d0db113 100644 --- a/main/src/cgeo/geocaching/sensors/RotationProvider.java +++ b/main/src/cgeo/geocaching/sensors/RotationProvider.java @@ -18,6 +18,18 @@ import android.hardware.SensorManager; public class RotationProvider { + /** + * On some Samsung devices, {@link SensorManager#getRotationMatrixFromVector} throws an exception if the rotation + * vector has more than 4 elements. + * <p/> + * This will be detected and remembered after the first occurrence of the exception. Concurrent access + * is not a problem as this variable can only go from {@code false} to {@code true} and being {@code false} + * instead of {@code true} is innocuous and will be changed immediately when needed. + * + * @see <a href="http://stackoverflow.com/a/22138449">this Stack Overflow answer</a> + */ + private static boolean isTruncationNeeded = false; + private RotationProvider() { // Utility class, not to be instantiated } @@ -43,14 +55,20 @@ public class RotationProvider { @Override public void onSensorChanged(final SensorEvent event) { - // On some Samsung devices, SensorManager#getRotationMatrixFromVector throws an exception if the rotation - // vector has more than 4 elements. Since only the four first elements are used, we can truncate the vector - // without losing precision. - if (event.values.length > 4) { + if (isTruncationNeeded) { + // Since only the four first elements are used (and accepted), we truncate the vector. System.arraycopy(event.values, 0, values, 0, 4); SensorManager.getRotationMatrixFromVector(rotationMatrix, values); } else { - SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values); + try { + SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values); + } catch (final IllegalArgumentException ignored) { + Log.d("installing workaround for mismatched number of values in rotation vector"); + // Install workaround and retry + isTruncationNeeded = true; + onSensorChanged(event); + return; + } } SensorManager.getOrientation(rotationMatrix, orientation); subscriber.onNext((float) (orientation[0] * 180 / Math.PI)); |