diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java index 45bc83bd..0d31eeb8 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java @@ -43,7 +43,6 @@ import android.widget.TextView; import android.widget.Toast; import com.cradle.iitc_mobile.IITC_NavigationHelper.Pane; -import com.cradle.iitc_mobile.prefs.PluginPreferenceActivity; import com.cradle.iitc_mobile.prefs.PreferenceActivity; import com.cradle.iitc_mobile.share.ShareActivity; @@ -723,6 +722,7 @@ public class IITC_Mobile extends Activity public void setLoadingState(final boolean isLoading) { mIsLoading = isLoading; mNavigationHelper.onLoadingStateChanged(); + mUserLocation.onLoadingStateChanged(); invalidateOptionsMenu(); updateViews(); if (!isLoading) mFileManager.updatePlugins(false); diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_UserLocation.java b/mobile/src/com/cradle/iitc_mobile/IITC_UserLocation.java index f43f49fc..4907effc 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_UserLocation.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_UserLocation.java @@ -1,42 +1,37 @@ package com.cradle.iitc_mobile; import android.content.Context; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.view.Surface; -public class IITC_UserLocation implements LocationListener, SensorEventListener { - private static final double SENSOR_DELAY_USER = 100 * 1e6; // 100 milliseconds +import com.cradle.iitc_mobile.compass.AccMagCompass; +import com.cradle.iitc_mobile.compass.Compass; +import com.cradle.iitc_mobile.compass.CompassListener; + +public class IITC_UserLocation implements CompassListener, LocationListener { private static final int TWO_MINUTES = 1000 * 60 * 2; + private final Compass mCompass; private boolean mFollowing = false; private final IITC_Mobile mIitc; private Location mLastLocation = null; - private long mLastUpdate = 0; private final LocationManager mLocationManager; private boolean mLocationRegistered = false; private int mMode = 0; private double mOrientation = 0; private boolean mOrientationRegistered = false; private boolean mRunning = false; - private final Sensor mSensorAccelerometer, mSensorMagnetometer; - private SensorManager mSensorManager = null; - private float[] mValuesGravity = null, mValuesGeomagnetic = null; public IITC_UserLocation(final IITC_Mobile iitc) { mIitc = iitc; + mCompass = new AccMagCompass(mIitc); + // Acquire a reference to the Location Manager and Sensor Manager mLocationManager = (LocationManager) iitc.getSystemService(Context.LOCATION_SERVICE); - mSensorManager = (SensorManager) iitc.getSystemService(Context.SENSOR_SERVICE); - mSensorAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); - mSensorMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); } // Checks whether two providers are the same @@ -64,8 +59,8 @@ public class IITC_UserLocation implements LocationListener, SensorEventListener } private void updateListeners() { - final boolean useLocation = mRunning && mMode != 0; - final boolean useOrientation = mRunning && mMode == 2; + final boolean useLocation = mRunning && mMode != 0 && !mIitc.isLoading(); + final boolean useOrientation = useLocation && mMode == 2; if (useLocation && !mLocationRegistered) { try { @@ -87,14 +82,12 @@ public class IITC_UserLocation implements LocationListener, SensorEventListener mLocationRegistered = false; } - if (useOrientation && !mOrientationRegistered && mSensorAccelerometer != null && mSensorMagnetometer != null) { - mSensorManager.registerListener(this, mSensorAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); - mSensorManager.registerListener(this, mSensorMagnetometer, SensorManager.SENSOR_DELAY_NORMAL); + if (useOrientation && !mOrientationRegistered) { + mCompass.registerListener(this); mOrientationRegistered = true; } - if (!useOrientation && mOrientationRegistered && mSensorAccelerometer != null && mSensorMagnetometer != null) { - mSensorManager.unregisterListener(this, mSensorAccelerometer); - mSensorManager.unregisterListener(this, mSensorMagnetometer); + if (!useOrientation && mOrientationRegistered) { + mCompass.unregisterListener(this); mOrientationRegistered = false; } } @@ -170,7 +163,27 @@ public class IITC_UserLocation implements LocationListener, SensorEventListener } @Override - public void onAccuracyChanged(final Sensor sensor, final int accuracy) { + public void onCompassChanged(final float x, final float y, final float z) { + double orientation = Math.toDegrees(x); + + final int rotation = mIitc.getWindowManager().getDefaultDisplay().getRotation(); + switch (rotation) { + case Surface.ROTATION_90: + orientation += 90; + break; + case Surface.ROTATION_180: + orientation += 180; + break; + case Surface.ROTATION_270: + orientation += 270; + break; + } + + setOrientation(orientation); + } + + public void onLoadingStateChanged() { + updateListeners(); } @Override @@ -195,48 +208,6 @@ public class IITC_UserLocation implements LocationListener, SensorEventListener public void onProviderEnabled(final String provider) { } - @Override - public void onSensorChanged(final SensorEvent event) { - if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) - mValuesGravity = event.values; - if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) - mValuesGeomagnetic = event.values; - - // save some battery, 10 updates per second should be enough - if ((event.timestamp - mLastUpdate) < SENSOR_DELAY_USER) return; - mLastUpdate = event.timestamp; - - // do not touch the javascript while iitc boots - if (mIitc.isLoading()) return; - - // wait until both sensors have given us an event - if (mValuesGravity == null || mValuesGeomagnetic == null) return; - - final float R[] = new float[9]; - final float I[] = new float[9]; - final float orientation[] = new float[3]; - - if (!SensorManager.getRotationMatrix(R, I, mValuesGravity, mValuesGeomagnetic)) return; - SensorManager.getOrientation(R, orientation); - - double direction = orientation[0] / Math.PI * 180; - - final int rotation = mIitc.getWindowManager().getDefaultDisplay().getRotation(); - switch (rotation) { - case Surface.ROTATION_90: - direction += 90; - break; - case Surface.ROTATION_180: - direction += 180; - break; - case Surface.ROTATION_270: - direction += 270; - break; - } - - setOrientation(direction); - } - public void onStart() { mRunning = true; updateListeners(); diff --git a/mobile/src/com/cradle/iitc_mobile/compass/AccMagCompass.java b/mobile/src/com/cradle/iitc_mobile/compass/AccMagCompass.java new file mode 100644 index 00000000..92b48f24 --- /dev/null +++ b/mobile/src/com/cradle/iitc_mobile/compass/AccMagCompass.java @@ -0,0 +1,74 @@ +package com.cradle.iitc_mobile.compass; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; + +public class AccMagCompass extends Compass { + private static final double SENSOR_DELAY_USER = 100 * 1e6; // 100 milliseconds + + private final Context mContext; + private long mLastUpdate = 0; + private final SensorListener mListener = new SensorListener(); + private final float[] mOrientation = new float[3]; + private final float[] mRotationMatrix = new float[9]; + private final Sensor mSensorAcc, mSensorMag; + private final SensorManager mSensorManager; + private float[] mValuesAcc = null, mValuesMag = null; + + public AccMagCompass(final Context context) { + mContext = context; + + mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); + + mSensorAcc = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + mSensorMag = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); + } + + private void calculateOrientation() { + + // wait until both sensors have given us an event + if (mValuesAcc == null || mValuesMag == null) return; + + if (!SensorManager.getRotationMatrix(mRotationMatrix, null, mValuesAcc, mValuesMag)) return; + SensorManager.getOrientation(mRotationMatrix, mOrientation); + + publishOrientation(mOrientation[0], mOrientation[1], mOrientation[2]); + } + + @Override + protected void onStart() { + mSensorManager.registerListener(mListener, mSensorAcc, SensorManager.SENSOR_DELAY_NORMAL); + mSensorManager.registerListener(mListener, mSensorMag, SensorManager.SENSOR_DELAY_NORMAL); + } + + @Override + protected void onStop() { + mSensorManager.unregisterListener(mListener); + } + + private class SensorListener implements SensorEventListener { + @Override + public void onAccuracyChanged(final Sensor sensor, final int accuracy) { + } + + @Override + public void onSensorChanged(final SensorEvent event) { + switch (event.sensor.getType()) { + case Sensor.TYPE_ACCELEROMETER: + mValuesAcc = event.values; + break; + case Sensor.TYPE_MAGNETIC_FIELD: + mValuesMag = event.values; + + // save some battery, 10 updates per second should be enough + if ((event.timestamp - mLastUpdate) < SENSOR_DELAY_USER) break; + mLastUpdate = event.timestamp; + + calculateOrientation(); + } + } + } +} diff --git a/mobile/src/com/cradle/iitc_mobile/compass/Compass.java b/mobile/src/com/cradle/iitc_mobile/compass/Compass.java new file mode 100644 index 00000000..b211ff9b --- /dev/null +++ b/mobile/src/com/cradle/iitc_mobile/compass/Compass.java @@ -0,0 +1,39 @@ +package com.cradle.iitc_mobile.compass; + +import java.util.ArrayList; + +public abstract class Compass +{ + private final ArrayList mListeners = new ArrayList(); + private boolean mStarted = false; + + protected void publishOrientation(final float x, final float y, final float z) + { + for (final CompassListener listener : mListeners) + listener.onCompassChanged(x, y, z); + } + + protected abstract void onStart(); + + protected abstract void onStop(); + + public void registerListener(final CompassListener listener) + { + mListeners.add(listener); + if (!mStarted) + { + onStart(); + mStarted = true; + } + } + + public void unregisterListener(final CompassListener listener) + { + mListeners.remove(listener); + if (mListeners.size() == 0) + { + onStop(); + mStarted = false; + } + } +} diff --git a/mobile/src/com/cradle/iitc_mobile/compass/CompassListener.java b/mobile/src/com/cradle/iitc_mobile/compass/CompassListener.java new file mode 100644 index 00000000..72e36e49 --- /dev/null +++ b/mobile/src/com/cradle/iitc_mobile/compass/CompassListener.java @@ -0,0 +1,5 @@ +package com.cradle.iitc_mobile.compass; + +public interface CompassListener { + public void onCompassChanged(float x, float y, float z); +}