Commit d7f254f6 authored by Jeffrey I. Schiller's avatar Jeffrey I. Schiller

Issue 65001 from Rietveld -- Sensor Time Interval and Distance "Debouncing"

parent d89d9325
...@@ -508,6 +508,44 @@ public interface OdeMessages extends Messages { ...@@ -508,6 +508,44 @@ public interface OdeMessages extends Messages {
@Description("Text for screen orientation choice 'Landscape '") @Description("Text for screen orientation choice 'Landscape '")
String landscapeScreenOrientation(); String landscapeScreenOrientation();
//Used in editor/youngandroid/properties/YoungAndroidSensorTimeIntervalChoicePropertyEditor.java
@DefaultMessage("0")
@Description("Text for time interval choice '0' milliseconds")
String zeroTimeInterval();
@DefaultMessage("1000")
@Description("Text for time interval choice '1000' milliseconds")
String oneThousandTimeInterval();
@DefaultMessage("10000")
@Description("Text for time interval choice '10000' milliseconds")
String tenThousandTimeInterval();
@DefaultMessage("60000")
@Description("Text for time interval choice '60000' milliseconds")
String sixtyThousandTimeInterval();
@DefaultMessage("300000")
@Description("Text for time interval choice '300000' milliseconds")
String threeHundredThousandTimeInterval();
//Used in editor/youngandroid/properties/YoungAndroidSensorDistIntervalChoicePropertyEditor.java
@DefaultMessage("0")
@Description("Text for distance interval choice '0 meters'")
String zeroDistanceInterval();
@DefaultMessage("1")
@Description("Text for distance interval choice '1 meter'")
String oneDistanceInterval();
@DefaultMessage("10")
@Description("Text for distance interval choice '10 meters'")
String tenDistanceInterval();
@DefaultMessage("100")
@Description("Text for distance interval choice '100 meters'")
String oneHundredDistanceInterval();
// Used in explorer/SourceStructureExplorer.java // Used in explorer/SourceStructureExplorer.java
@DefaultMessage("Rename") @DefaultMessage("Rename")
......
...@@ -19,6 +19,8 @@ import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroid ...@@ -19,6 +19,8 @@ import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroid
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidFontTypefaceChoicePropertyEditor; import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidFontTypefaceChoicePropertyEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLegoNxtSensorPortChoicePropertyEditor; import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLegoNxtSensorPortChoicePropertyEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidScreenOrientationChoicePropertyEditor; import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidScreenOrientationChoicePropertyEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidSensorDistIntervalChoicePropertyEditor;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidSensorTimeIntervalChoicePropertyEditor;
import com.google.appinventor.client.widgets.properties.FloatPropertyEditor; import com.google.appinventor.client.widgets.properties.FloatPropertyEditor;
import com.google.appinventor.client.widgets.properties.IntegerPropertyEditor; import com.google.appinventor.client.widgets.properties.IntegerPropertyEditor;
import com.google.appinventor.client.widgets.properties.NonNegativeFloatPropertyEditor; import com.google.appinventor.client.widgets.properties.NonNegativeFloatPropertyEditor;
...@@ -168,6 +170,10 @@ public class YoungAndroidPalettePanel extends Composite implements SimplePalette ...@@ -168,6 +170,10 @@ public class YoungAndroidPalettePanel extends Composite implements SimplePalette
return new NonNegativeIntegerPropertyEditor(); return new NonNegativeIntegerPropertyEditor();
} else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_SCREEN_ORIENTATION)) { } else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_SCREEN_ORIENTATION)) {
return new YoungAndroidScreenOrientationChoicePropertyEditor(); return new YoungAndroidScreenOrientationChoicePropertyEditor();
} else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_SENSOR_DIST_INTERVAL)) {
return new YoungAndroidSensorDistIntervalChoicePropertyEditor();
} else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_SENSOR_TIME_INTERVAL)) {
return new YoungAndroidSensorTimeIntervalChoicePropertyEditor();
} else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_STRING)) { } else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_STRING)) {
return new StringPropertyEditor(); return new StringPropertyEditor();
} else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_TEXTALIGNMENT)) { } else if (editorType.equals(PropertyTypeConstants.PROPERTY_TYPE_TEXTALIGNMENT)) {
......
package com.google.appinventor.client.editor.youngandroid.properties;
import static com.google.appinventor.client.Ode.MESSAGES;
import com.google.appinventor.client.widgets.properties.ChoicePropertyEditor;
import com.google.appinventor.client.widgets.properties.ChoicePropertyEditor.Choice;
/**
* Property editor for sensor distance notification intervals
*
* @author abhagi@mit.edu (Anshul Bhagi)
*/
public class YoungAndroidSensorDistIntervalChoicePropertyEditor extends ChoicePropertyEditor {
// sensor distance interval choices
private static final Choice[] distIntervalChoices = new Choice[] {
// To avoid confusion, we only show a subset of the available sensor
// distance interval values.
new Choice(MESSAGES.zeroDistanceInterval(), "0"),
new Choice(MESSAGES.oneDistanceInterval(), "1"),
new Choice(MESSAGES.tenDistanceInterval(), "10"),
new Choice(MESSAGES.oneHundredDistanceInterval(), "100"),
};
public YoungAndroidSensorDistIntervalChoicePropertyEditor() {
super(distIntervalChoices);
}
}
// Copyright 2012 MIT. All Rights Reserved.
package com.google.appinventor.client.editor.youngandroid.properties;
import static com.google.appinventor.client.Ode.MESSAGES;
import com.google.appinventor.client.widgets.properties.ChoicePropertyEditor;
import com.google.appinventor.client.widgets.properties.ChoicePropertyEditor.Choice;
/**
* Property editor for sensor time notification intervals
*
* @author abhagi@mit.edu (Anshul Bhagi)
*/
public class YoungAndroidSensorTimeIntervalChoicePropertyEditor extends ChoicePropertyEditor{
// sensor time interval choices
private static final Choice[] timeIntervalChoices = new Choice[] {
// To avoid confusion, we only show a subset of the available
// sensor time interval values.
new Choice(MESSAGES.zeroTimeInterval(), "0"),
new Choice(MESSAGES.oneThousandTimeInterval(), "1000"),
new Choice(MESSAGES.tenThousandTimeInterval(), "10000"),
new Choice(MESSAGES.sixtyThousandTimeInterval(), "60000"),
new Choice(MESSAGES.threeHundredThousandTimeInterval(), "300000"),
};
public YoungAndroidSensorTimeIntervalChoicePropertyEditor() {
super(timeIntervalChoices);
}
}
...@@ -240,6 +240,9 @@ public final class YoungAndroidFormUpgrader { ...@@ -240,6 +240,9 @@ public final class YoungAndroidFormUpgrader {
} else if (componentType.equals("ListPicker")) { } else if (componentType.equals("ListPicker")) {
srcCompVersion = upgradeListPickerProperties(componentProperties, srcCompVersion); srcCompVersion = upgradeListPickerProperties(componentProperties, srcCompVersion);
} else if (componentType.equals("LocationSensor")) {
srcCompVersion = upgradeLocationSensorProperties(componentProperties, srcCompVersion);
} else if (componentType.equals("OrientationSensor")) { } else if (componentType.equals("OrientationSensor")) {
srcCompVersion = upgradeOrientationSensorProperties(componentProperties, srcCompVersion); srcCompVersion = upgradeOrientationSensorProperties(componentProperties, srcCompVersion);
...@@ -634,6 +637,16 @@ public final class YoungAndroidFormUpgrader { ...@@ -634,6 +637,16 @@ public final class YoungAndroidFormUpgrader {
return srcCompVersion; return srcCompVersion;
} }
private static int upgradeLocationSensorProperties(Map<String, JSONValue> componentProperties,
int srcCompVersion) {
if (srcCompVersion < 2) {
// The TimeInterval and DistanceInterval properties were added.
// No properties need to be modified to upgrade to Version 2.
srcCompVersion = 2;
}
return srcCompVersion;
}
private static int upgradeOrientationSensorProperties( private static int upgradeOrientationSensorProperties(
Map<String, JSONValue> componentProperties, int srcCompVersion) { Map<String, JSONValue> componentProperties, int srcCompVersion) {
if (srcCompVersion < 2) { if (srcCompVersion < 2) {
......
...@@ -427,6 +427,9 @@ public class BlockSaveFile { ...@@ -427,6 +427,9 @@ public class BlockSaveFile {
} else if (genus.equals("ListPicker")) { } else if (genus.equals("ListPicker")) {
blkCompVersion = upgradeListPickerBlocks(blkCompVersion, componentName); blkCompVersion = upgradeListPickerBlocks(blkCompVersion, componentName);
} else if (genus.equals("LocationSensor")) {
blkCompVersion = upgradeLocationSensorBlocks(blkCompVersion, componentName);
} else if (genus.equals("OrientationSensor")) { } else if (genus.equals("OrientationSensor")) {
blkCompVersion = upgradeOrientationSensorBlocks(blkCompVersion, componentName); blkCompVersion = upgradeOrientationSensorBlocks(blkCompVersion, componentName);
...@@ -790,6 +793,16 @@ public class BlockSaveFile { ...@@ -790,6 +793,16 @@ public class BlockSaveFile {
return blkCompVersion; return blkCompVersion;
} }
private int upgradeLocationSensorBlocks(int blkCompVersion, String componentName) {
if (blkCompVersion < 2) {
// The TimeInterval and DistanceInterval properties were added.
// No changes required.
blkCompVersion = 2;
}
return blkCompVersion;
}
private int upgradeOrientationSensorBlocks(int blkCompVersion, String componentName) { private int upgradeOrientationSensorBlocks(int blkCompVersion, String componentName) {
if (blkCompVersion < 2) { if (blkCompVersion < 2) {
// The Yaw property was renamed to Azimuth. // The Yaw property was renamed to Azimuth.
......
...@@ -93,6 +93,18 @@ public class PropertyTypeConstants { ...@@ -93,6 +93,18 @@ public class PropertyTypeConstants {
*/ */
public static final String PROPERTY_TYPE_SCREEN_ORIENTATION = "screen_orientation"; public static final String PROPERTY_TYPE_SCREEN_ORIENTATION = "screen_orientation";
/**
* Minimum distance interval, in meters, that the location sensor will try to use
* for sending out location updates. See {@link com.google.appinventor.components.runtime.LocationSensor}.
*/
public static final String PROPERTY_TYPE_SENSOR_DIST_INTERVAL = "sensor_dist_interval";
/**
* Minimum time interval, in milliseconds, that the location sensor use to send out
* location updates. See {@link com.google.appinventor.components.runtime.LocationSensor}.
*/
public static final String PROPERTY_TYPE_SENSOR_TIME_INTERVAL = "sensor_time_interval";
/** /**
* Strings. This has the same effect as, but is preferred in component * Strings. This has the same effect as, but is preferred in component
* definitions to, {@link #PROPERTY_TYPE_TEXT}). * definitions to, {@link #PROPERTY_TYPE_TEXT}).
......
...@@ -170,8 +170,10 @@ public class YaVersion { ...@@ -170,8 +170,10 @@ public class YaVersion {
// - PHONENUMBERPICKER_COMPONENT_VERSION was incremented to 4. // - PHONENUMBERPICKER_COMPONENT_VERSION was incremented to 4.
// For YOUNG_ANDROID_VERSION 55: // For YOUNG_ANDROID_VERSION 55:
// - ACCELEROMETERSENSOR_COMPONENT_VERSION was incremented to 2. // - ACCELEROMETERSENSOR_COMPONENT_VERSION was incremented to 2.
// For YOUNG_ANDROID_VERSION 56
// - LOCATIONSENSOR_COMPONENT_VERSION was incremented to 2
public static final int YOUNG_ANDROID_VERSION = 55; public static final int YOUNG_ANDROID_VERSION = 56;
// ............................... Blocks Language Version Number ............................... // ............................... Blocks Language Version Number ...............................
...@@ -390,7 +392,9 @@ public class YaVersion { ...@@ -390,7 +392,9 @@ public class YaVersion {
// - The Shape property was added. // - The Shape property was added.
public static final int LISTPICKER_COMPONENT_VERSION = 5; public static final int LISTPICKER_COMPONENT_VERSION = 5;
public static final int LOCATIONSENSOR_COMPONENT_VERSION = 1; // For LOCATIONSENSOR_COMPONENT_VERSION 2:
// - The TimeInterval and DistanceInterval properties were added.
public static final int LOCATIONSENSOR_COMPONENT_VERSION = 2;
public static final int NOTIFIER_COMPONENT_VERSION = 1; public static final int NOTIFIER_COMPONENT_VERSION = 1;
......
...@@ -134,19 +134,6 @@ public class LocationSensor extends AndroidNonvisibleComponent ...@@ -134,19 +134,6 @@ public class LocationSensor extends AndroidNonvisibleComponent
*/ */
public static final int UNKNOWN_VALUE = 0; public static final int UNKNOWN_VALUE = 0;
/**
* Minimum time in milliseconds between location checks. The documentation for
* {@link android.location.LocationManager#requestLocationUpdates}
* does not recommend using a location lower than 60,000 (60 seconds) because
* of power consumption.
*/
public static final long MIN_TIME_INTERVAL = 60000;
/**
* Minimum distance in meters to be reported
*/
public static final long MIN_DISTANCE_INTERVAL = 5; // 5 meters
// These variables contain information related to the LocationProvider. // These variables contain information related to the LocationProvider.
private final Criteria locationCriteria; private final Criteria locationCriteria;
private final Handler handler; private final Handler handler;
...@@ -154,8 +141,11 @@ public class LocationSensor extends AndroidNonvisibleComponent ...@@ -154,8 +141,11 @@ public class LocationSensor extends AndroidNonvisibleComponent
private boolean providerLocked = false; // if true we can't change providerName private boolean providerLocked = false; // if true we can't change providerName
private String providerName; private String providerName;
// Invariant: providerLocked => providerName is non-empty // Invariant: providerLocked => providerName is non-empty
private int timeInterval;
private int distanceInterval;
private MyLocationListener myLocationListener; private MyLocationListener myLocationListener;
private LocationProvider locationProvider; private LocationProvider locationProvider;
...@@ -193,12 +183,17 @@ public class LocationSensor extends AndroidNonvisibleComponent ...@@ -193,12 +183,17 @@ public class LocationSensor extends AndroidNonvisibleComponent
form.registerForOnResume(this); form.registerForOnResume(this);
form.registerForOnStop(this); form.registerForOnStop(this);
// Initialize sensor properties (60 seconds; 5 meters)
timeInterval = 60000;
distanceInterval = 5;
// Initialize location-related fields // Initialize location-related fields
Context context = container.$context(); Context context = container.$context();
geocoder = new Geocoder(context); geocoder = new Geocoder(context);
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
locationCriteria = new Criteria(); locationCriteria = new Criteria();
myLocationListener = new MyLocationListener(); myLocationListener = new MyLocationListener();
} }
// Events // Events
...@@ -262,8 +257,9 @@ public class LocationSensor extends AndroidNonvisibleComponent ...@@ -262,8 +257,9 @@ public class LocationSensor extends AndroidNonvisibleComponent
} }
/** /**
* Indicates whether the sensor should listen for location changes * Indicates whether the sensor should allow the developer to
* and raise the corresponding events. * manually change the provider (GPS, GSM, Wifi, etc.)
* from which location updates are received.
*/ */
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN, @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN,
defaultValue = "False") defaultValue = "False")
...@@ -271,7 +267,65 @@ public class LocationSensor extends AndroidNonvisibleComponent ...@@ -271,7 +267,65 @@ public class LocationSensor extends AndroidNonvisibleComponent
public void ProviderLocked(boolean lock) { public void ProviderLocked(boolean lock) {
providerLocked = lock; providerLocked = lock;
} }
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_SENSOR_TIME_INTERVAL,
defaultValue = "60000")
@SimpleProperty
public void TimeInterval(int interval) {
// make sure that the provided value is a valid one.
// choose 1000000 miliseconds to be the upper limit
if (interval < 0 || interval > 1000000)
return;
timeInterval = interval;
// restart listening for location updates, using the new time interval
if (enabled) {
RefreshProvider();
}
}
@SimpleProperty(
description = "Determines the minimum time interval, in milliseconds, that the sensor will try " +
"to use for sending out location updates. However, location updates will only be received " +
"when the location of the phone actually changes, and use of the specified time interval " +
"is not guaranteed. For example, if 1000 is used as the time interval, location updates will " +
"never be fired sooner than 1000ms, but they may be fired anytime after.",
category = PropertyCategory.BEHAVIOR)
public int TimeInterval() {
return timeInterval;
}
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_SENSOR_DIST_INTERVAL,
defaultValue = "5")
@SimpleProperty
public void DistanceInterval(int interval) {
// make sure that the provided value is a valid one.
// choose 1000 meters to be the upper limit
if (interval < 0 || interval > 1000)
return;
distanceInterval = interval;
// restart listening for location updates, using the new distance interval
if (enabled) {
RefreshProvider();
}
}
@SimpleProperty(
description = "Determines the minimum distance interval, in meters, that the sensor will try " +
"to use for sending out location updates. For example, if this is set to 5, then the sensor will " +
"fire a LocationChanged event only after 5 meters have been traversed. However, the sensor does " +
"not guarantee that an update will be received at exactly the distance interval. It may take more " +
"than 5 meters to fire an event, for instance.",
category = PropertyCategory.BEHAVIOR)
public int DistanceInterval() {
return distanceInterval;
}
/** /**
* Indicates whether longitude and latitude information is available. (It is * Indicates whether longitude and latitude information is available. (It is
* always the case that either both or neither are.) * always the case that either both or neither are.)
...@@ -487,8 +541,8 @@ public class LocationSensor extends AndroidNonvisibleComponent ...@@ -487,8 +541,8 @@ public class LocationSensor extends AndroidNonvisibleComponent
} }
stopListening(); stopListening();
locationProvider = tLocationProvider; locationProvider = tLocationProvider;
locationManager.requestLocationUpdates(providerName, MIN_TIME_INTERVAL, locationManager.requestLocationUpdates(providerName, timeInterval,
MIN_DISTANCE_INTERVAL, myLocationListener); distanceInterval, myLocationListener);
listening = true; listening = true;
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment