Move compass to separate class

This commit is contained in:
fkloft 2015-01-22 16:10:56 +01:00
parent 06b64f585b
commit cd8186ffa3
5 changed files with 154 additions and 65 deletions

View File

@ -43,7 +43,6 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.cradle.iitc_mobile.IITC_NavigationHelper.Pane; 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.prefs.PreferenceActivity;
import com.cradle.iitc_mobile.share.ShareActivity; import com.cradle.iitc_mobile.share.ShareActivity;
@ -723,6 +722,7 @@ public class IITC_Mobile extends Activity
public void setLoadingState(final boolean isLoading) { public void setLoadingState(final boolean isLoading) {
mIsLoading = isLoading; mIsLoading = isLoading;
mNavigationHelper.onLoadingStateChanged(); mNavigationHelper.onLoadingStateChanged();
mUserLocation.onLoadingStateChanged();
invalidateOptionsMenu(); invalidateOptionsMenu();
updateViews(); updateViews();
if (!isLoading) mFileManager.updatePlugins(false); if (!isLoading) mFileManager.updatePlugins(false);

View File

@ -1,42 +1,37 @@
package com.cradle.iitc_mobile; package com.cradle.iitc_mobile;
import android.content.Context; 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.Location;
import android.location.LocationListener; import android.location.LocationListener;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
import android.view.Surface; import android.view.Surface;
public class IITC_UserLocation implements LocationListener, SensorEventListener { import com.cradle.iitc_mobile.compass.AccMagCompass;
private static final double SENSOR_DELAY_USER = 100 * 1e6; // 100 milliseconds 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 static final int TWO_MINUTES = 1000 * 60 * 2;
private final Compass mCompass;
private boolean mFollowing = false; private boolean mFollowing = false;
private final IITC_Mobile mIitc; private final IITC_Mobile mIitc;
private Location mLastLocation = null; private Location mLastLocation = null;
private long mLastUpdate = 0;
private final LocationManager mLocationManager; private final LocationManager mLocationManager;
private boolean mLocationRegistered = false; private boolean mLocationRegistered = false;
private int mMode = 0; private int mMode = 0;
private double mOrientation = 0; private double mOrientation = 0;
private boolean mOrientationRegistered = false; private boolean mOrientationRegistered = false;
private boolean mRunning = 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) { public IITC_UserLocation(final IITC_Mobile iitc) {
mIitc = iitc; mIitc = iitc;
mCompass = new AccMagCompass(mIitc);
// Acquire a reference to the Location Manager and Sensor Manager // Acquire a reference to the Location Manager and Sensor Manager
mLocationManager = (LocationManager) iitc.getSystemService(Context.LOCATION_SERVICE); 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 // Checks whether two providers are the same
@ -64,8 +59,8 @@ public class IITC_UserLocation implements LocationListener, SensorEventListener
} }
private void updateListeners() { private void updateListeners() {
final boolean useLocation = mRunning && mMode != 0; final boolean useLocation = mRunning && mMode != 0 && !mIitc.isLoading();
final boolean useOrientation = mRunning && mMode == 2; final boolean useOrientation = useLocation && mMode == 2;
if (useLocation && !mLocationRegistered) { if (useLocation && !mLocationRegistered) {
try { try {
@ -87,14 +82,12 @@ public class IITC_UserLocation implements LocationListener, SensorEventListener
mLocationRegistered = false; mLocationRegistered = false;
} }
if (useOrientation && !mOrientationRegistered && mSensorAccelerometer != null && mSensorMagnetometer != null) { if (useOrientation && !mOrientationRegistered) {
mSensorManager.registerListener(this, mSensorAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); mCompass.registerListener(this);
mSensorManager.registerListener(this, mSensorMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);
mOrientationRegistered = true; mOrientationRegistered = true;
} }
if (!useOrientation && mOrientationRegistered && mSensorAccelerometer != null && mSensorMagnetometer != null) { if (!useOrientation && mOrientationRegistered) {
mSensorManager.unregisterListener(this, mSensorAccelerometer); mCompass.unregisterListener(this);
mSensorManager.unregisterListener(this, mSensorMagnetometer);
mOrientationRegistered = false; mOrientationRegistered = false;
} }
} }
@ -170,7 +163,27 @@ public class IITC_UserLocation implements LocationListener, SensorEventListener
} }
@Override @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 @Override
@ -195,48 +208,6 @@ public class IITC_UserLocation implements LocationListener, SensorEventListener
public void onProviderEnabled(final String provider) { 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() { public void onStart() {
mRunning = true; mRunning = true;
updateListeners(); updateListeners();

View File

@ -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();
}
}
}
}

View File

@ -0,0 +1,39 @@
package com.cradle.iitc_mobile.compass;
import java.util.ArrayList;
public abstract class Compass
{
private final ArrayList<CompassListener> mListeners = new ArrayList<CompassListener>();
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;
}
}
}

View File

@ -0,0 +1,5 @@
package com.cradle.iitc_mobile.compass;
public interface CompassListener {
public void onCompassChanged(float x, float y, float z);
}