package actions;
import geo.GeoUtils;
import system.EventManager;
import android.app.Activity;
import android.app.Dialog;
import android.location.Location;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public abstract class ActionWaitForAccuracy2 extends Action {
private static final String TEXT_DIALOG_TITLE = "Do you want to cancel the accuracy detection?";
private static final String TEXT_SKIP_ACCURACY_DETECTION = "Skip accuracy detection (not recomended!)";
// 1 minutes in ms:
private static final long MAX_TIME_SINCE_LAST_UPDATE_IN_MS = 1000 * 60 * 1;
private static final String LOG_TAG = "ActionWaitForAccuracy";
private float myCurrentAccuracy;
private float myMinAccuracy;
private boolean firstTimeReached = false;
private int myMaxPosUpdateCount;
private int stepCounter = 0;
private Activity myActivity;
/**
* @param context
* @param minAccuracy
* should be >= 25m
* @param maxPosUpdateCount
* The max number of update events before the position should be
* accurate enough (something around 6)
*/
public ActionWaitForAccuracy2(Activity context, float minAccuracy,
int maxPosUpdateCount) {
myActivity = context;
myMinAccuracy = minAccuracy;
myMaxPosUpdateCount = maxPosUpdateCount;
analyseInitLocation(GeoUtils.getCurrentLocation(context));
}
private void analyseInitLocation(Location l) {
if (l != null) {
myCurrentAccuracy = l.getAccuracy();
long passedTime = System.currentTimeMillis() - l.getTime();
Log.d(LOG_TAG, "Passed time since last location event="
+ (passedTime / 1000f / 10f) + " minutes");
if (passedTime <= MAX_TIME_SINCE_LAST_UPDATE_IN_MS)
onLocationChanged(l);
} else {
GeoUtils.enableLocationProvidersIfNeeded(myActivity);
}
}
@Override
public boolean onLocationChanged(Location l) {
Log.d(LOG_TAG, "Current signal accuracy=" + l.getAccuracy());
Log.d(LOG_TAG, "Minimum needed accuracy=" + myMinAccuracy);
Log.d(LOG_TAG, "Current pos update count=" + stepCounter);
Log.d(LOG_TAG, "Max pos updates=" + myMaxPosUpdateCount);
stepCounter++;
myCurrentAccuracy = l.getAccuracy();
updateUI(myActivity, (int) (myMinAccuracy / myCurrentAccuracy * 100),
stepCounter);
if ((myCurrentAccuracy != 0 && myCurrentAccuracy <= myMinAccuracy)
|| (stepCounter >= myMaxPosUpdateCount)) {
callFirstTimeAccReachedIfNotYetCalled(l);
}
return true;
}
/**
* This method is for display purpose only. If the UI does not have to react
* on updates do not do anything here
*
* @param activity
* @param neededAccuracyInPercent
* @param numberOfMeasurments
*/
public abstract void updateUI(Activity activity,
int neededAccuracyInPercent, int numberOfMeasurments);
private void callFirstTimeAccReachedIfNotYetCalled(Location location) {
if (!firstTimeReached) {
firstTimeReached = true;
Log.d(LOG_TAG, "Required accuracy was reached!");
minAccuracyReachedFirstTime(location, this);
} else
Log.w(LOG_TAG, "callFirstTimeAccReachedIfNotYetCalled was "
+ "called more then one time! This action should "
+ "be removed once the accuracy was reached!");
}
/**
* @param location
* The {@link Location} object that was accurate enough
* @param a
* the {@link ActionWaitForAccuracy2} object which can be used to
* remove it from the {@link EventListenerGroup} it was contained
* in (e.g. the {@link EventManager#onLocationChangedList})
*/
public abstract void minAccuracyReachedFirstTime(Location location,
ActionWaitForAccuracy2 a);
private void waitSomeSecondsAndThenRegisterForGPSEvents() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
EventManager.getInstance().registerLocationUpdates();
onGPSActivatedEvent();
}
}).start();
}
/**
* Override this if you need additional custom behavior as soon as the user
* activates GPS
*/
public void onGPSActivatedEvent() {
// on default do nothing
}
/**
* call this if the user should be able to skip this procedure
*/
public void showSkipPositionDetectionDialog() {
final Dialog dialog = new Dialog(myActivity);
Button b = new Button(myActivity);
b.setText(TEXT_SKIP_ACCURACY_DETECTION);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
callFirstTimeAccReachedIfNotYetCalled(GeoUtils
.getCurrentLocation(myActivity));
dialog.dismiss();
}
});
dialog.setContentView(b);
dialog.setTitle(TEXT_DIALOG_TITLE);
dialog.setCanceledOnTouchOutside(true);
dialog.show();
}
}