Skip to content
Permalink
Browse files

Adding two new widgets. "bearing" of type decimal, appearance="bearin…

…g" which uses the compass to get direction. "url" of type string, appearance="url", which attempts to load whatever is saved as an answer in the browser.
  • Loading branch information...
chartung
chartung committed Oct 16, 2013
1 parent 8524220 commit 117f56290dde6ac86f8a07615fd0ec89a63d3bc9
@@ -163,6 +163,9 @@
<activity
android:name=".activities.GeoPointMapActivitySdk7"
android:label="@string/app_name" />
<activity
android:name=".activities.BearingActivity"
android:label="@string/app_name" />
<activity
android:name=".activities.SplashScreenActivity"
android:label="@string/app_name"
@@ -255,4 +255,9 @@
<string name="constraint_behavior_on_swipe">Validate upon forward swipe</string>
<string name="constraint_behavior_on_finalize">Defer validation until finalized</string>
<string name="view_change_location">View or Change Location</string>
<string name="open_url">Open Url</string>
<string name="get_bearing">Record Bearing</string>
<string name="replace_bearing">Replace Bearing</string>
<string name="getting_bearing">Loading Bearing</string>
<string name="accept_bearing">Record Bearing</string>
</resources>
@@ -0,0 +1,201 @@
/*
* Copyright (C) 2013 Nafundi
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

package org.odk.collect.android.activities;

import org.odk.collect.android.R;
import org.odk.collect.android.application.Collect;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;

public class BearingActivity extends Activity implements SensorEventListener {
private ProgressDialog mBearingDialog;

private SensorManager mSensorManager;
private Sensor accelerometer;
private Sensor magnetometer;

private static float[] mAccelerometer = null;
private static float[] mGeomagnetic = null;

private String mBearing = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(getString(R.string.app_name) + " > " + getString(R.string.get_bearing));

mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

setupBearingDialog();
}

@Override
protected void onPause() {
super.onPause();

mSensorManager.unregisterListener(this, accelerometer);
mSensorManager.unregisterListener(this, magnetometer);

if (mBearingDialog != null && mBearingDialog.isShowing())
mBearingDialog.dismiss();
}

@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_GAME);
mBearingDialog.show();
}

@Override
protected void onStart() {
super.onStart();
Collect.getInstance().getActivityLogger().logOnStart(this);
}

@Override
protected void onStop() {
Collect.getInstance().getActivityLogger().logOnStop(this);
super.onStop();
}

/**
* Sets up the look and actions for the progress dialog while the compass is
* searching.
*/
private void setupBearingDialog() {
Collect.getInstance().getActivityLogger()
.logInstanceAction(this, "setupBearingDialog", "show");
// dialog displayed while fetching bearing
mBearingDialog = new ProgressDialog(this);
DialogInterface.OnClickListener geopointButtonListener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON1:
Collect.getInstance().getActivityLogger()
.logInstanceAction(this, "acceptBearing", "OK");
returnBearing();
break;
case DialogInterface.BUTTON2:
Collect.getInstance().getActivityLogger()
.logInstanceAction(this, "cancelBearing", "cancel");
mBearing = null;
finish();
break;
}
}
};

// back button doesn't cancel
mBearingDialog.setCancelable(false);
mBearingDialog.setIndeterminate(true);
mBearingDialog.setIcon(android.R.drawable.ic_dialog_info);
mBearingDialog.setTitle(getString(R.string.getting_bearing));
mBearingDialog.setMessage(getString(R.string.please_wait_long));
mBearingDialog.setButton(DialogInterface.BUTTON1, getString(R.string.accept_bearing),
geopointButtonListener);
mBearingDialog.setButton(DialogInterface.BUTTON2, getString(R.string.cancel_location),
geopointButtonListener);
}

private void returnBearing() {
if (mBearing != null) {
Intent i = new Intent();
i.putExtra(
FormEntryActivity.BEARING_RESULT, mBearing);
setResult(RESULT_OK, i);
}
finish();
}

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub

}

@Override
public void onSensorChanged(SensorEvent event) {
// onSensorChanged gets called for each sensor so we have to remember
// the values
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mAccelerometer = event.values;
}

if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
mGeomagnetic = event.values;
}

if (mAccelerometer != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mAccelerometer, mGeomagnetic);

if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
// at this point, orientation contains the azimuth(direction),
// pitch and roll values.
double azimuth = 180 * orientation[0] / Math.PI;
// double pitch = 180 * orientation[1] / Math.PI;
// double roll = 180 * orientation[2] / Math.PI;
double degrees = normalizeDegree(azimuth);
mBearing = String.format("%.3f", degrees);
String dir = "N";
if ((degrees > 0 && degrees <= 22.5) || degrees > 337.5) {
dir = "N";
} else if (degrees > 22.5 && degrees <= 67.5) {
dir = "NE";
} else if (degrees > 67.5 && degrees <= 112.5) {
dir = "E";
} else if (degrees > 112.5 && degrees <= 157.5) {
dir = "SE";
} else if (degrees > 157.5 && degrees <= 222.5) {
dir = "S";
} else if (degrees > 222.5 && degrees <= 247.5) {
dir = "SW";
} else if (degrees > 247.5 && degrees <= 292.5) {
dir = "W";
} else if (degrees > 292.5 && degrees <= 337.5) {
dir = "NW";
}
mBearingDialog.setMessage("Dir: " + dir + " Bearing: " + mBearing);

}
}
}

private double normalizeDegree(double value) {
if (value >= 0.0f && value <= 180.0f) {
return value;
} else {
return 180 + (180 + value);
}
}

}
@@ -139,9 +139,11 @@
public static final int SIGNATURE_CAPTURE = 14;
public static final int ANNOTATE_IMAGE = 15;
public static final int ALIGNED_IMAGE = 16;
public static final int BEARING_CAPTURE = 17;

// Extra returned from gp activity
public static final String LOCATION_RESULT = "LOCATION_RESULT";
public static final String BEARING_RESULT = "BEARING_RESULT";

public static final String KEY_INSTANCES = "instances";
public static final String KEY_SUCCESS = "success";
@@ -694,6 +696,10 @@ protected void onActivityResult(int requestCode, int resultCode,
((ODKView) mCurrentView).setBinaryData(sl);
saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
break;
case BEARING_CAPTURE:
String bearing = intent.getStringExtra(BEARING_RESULT);
((ODKView) mCurrentView).setBinaryData(bearing);
saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
case HIERARCHY_ACTIVITY:
// We may have jumped to a new index in hierarchy activity, so
// refresh

0 comments on commit 117f562

Please sign in to comment.
You can’t perform that action at this time.