barbeau / gpstest Goto Github PK
View Code? Open in Web Editor NEWThe #1 open-source Android GNSS/GPS test program
License: Apache License 2.0
The #1 open-source Android GNSS/GPS test program
License: Apache License 2.0
As pointed out in the comments here:
http://stackoverflow.com/a/17757853/937715
(which links to the NavigationDrawer docs)
...the default for margin swipe for normal Android UI elements such as the Navigation Drawer appears to be 20 dp.
Excerpt from above link:
If the user touches the very left edge of the screen (within 20 dp from the left), have the drawer peek out as soon as the finger makes contact with the display. This promotes accidental discovery and provides richer feedback.
So, we should use this value too.
Right now these parameters are hard-coded at 1s and 0m, respectively. We should allow the user to set these.
A switch should be added to the Action Bar to handle turning GPS on or off, since this is one of the primary actions a user would take and a switch is a good visual representation of on/off control.
Switch widget is only available on API level 14 or higher.
This library looks like it may be a good option to offer Switch on API levels under 14.
https://github.com/BoD/android-switch-backport
It can be hard to visually distinguish rows on the GPS Status screen, especially in landscape due to length of screen. We should look at lightly shading every other row to make row definition clearer.
Feature requested by a user:
Favourite since day one neet update but i still miss keep screen awake when in app / obtaining fix in options or ticker :-)
Hi!
I bought a phone that supposedly has a galileo positioning module built in. Unfortunately I have no idea how to verify that. How can I check with this app which positioning systems I can access?
We should information about how to use the app, as well as multiple attributions here, including to Mike Lockwood for original development of app, as well as attribution for Google Maps API v2:
If you use the Google Maps Android API in your application, you must include the Google Play Services attribution text as part of a "Legal Notices" section in your application. Including legal notices as an independent menu item, or as part of an "About" menu item, is recommended.
The attribution text is available by making a call to GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo
Some issues must be resolved during migration, related to library project build config, as discussed here:
http://tools.android.com/tech-docs/new-build-system/migrating_to_09
Label it "Analyze GPS Accuracy", and link it to Google Play:
https://play.google.com/store/apps/details?id=com.gpsbenchmark.android
Only show this preference on devices that support the rotation vector sensor.
I've received several requests to offer a maps-free version of the app, both so it could be included in an open-source market such as F-Droid (see discussion on adding GPSTest to F-Droid here), as well as removing the requirement to download and install Google Play Services (which some users dislike with a passion).
We should be able to do this via build flavors in Gradle, and still support both versions (maps and no-maps) going forward.
One question is if we distribute the no-maps version via Google Play, or just offer the APK for sideloading off the website or downloading via F-Droid.
Users have requested this feature. Instead of manually hitting "Menu->Start", GPS should automatically start when starting up the app. We should also add a preference for disabling this feature.
We should rotate the map with the compass by default to match the sky view, since this is now possible with Maps API v2. However, we should also make the implementation smart enough to allow the user to browse the map when they want, and not always force auto-rotation. Handle My Location button click, and temporarily disable compass-based movement, so My Location button works. We should also give the user the option to turn off map auto-rotate in preferences.
Currently the raw GPS altitude is shown in the app, which is the distance above the surface of the WGS84 ellipsoid in meters.
Users have requested the ability to apply an adjustment via a setting to show the altitude as the distance above mean sea level, which is more meaningful in certain use cases.
Since the distance between mean sea level and the surface of the WGS84 ellipsoid varies depending on your latitude and longitude, we will need to include a look-up table in the app (or fetch dynamically via web service) so that we can apply the proper adjustment.
More info below:
http://stackoverflow.com/questions/11168306/is-androids-gps-altitude-incorrect-due-to-not-including-geoid-height
Earth Gravitational Model 2008 (EGM2008) maps the difference in mean sea level with the ellipsoid as a function of longitude and latitude:
http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008/egm08_wgs84.html
ActionBarSherlock has been deprecated for over a year - in mid-2013 Jake Wharton announced that work on ABS would cease. One primary motivator was the release of the official Android ActionBarCompat library. ABS is also missing native support for the NavigationDrawer. We should change to using the ActionBarCompat library.
Maps API v2 uses fragments natively and is therefore a better fit when using an ActionBar and tabs with fragments than Maps API v1.
This may be by design to indicate how many seconds have passed when various intervals are used, but with an interval of 0 this field always reads "in 0 seconds", which isn't very useful. If "0" seconds has passed we may want to show the actual time instead of the elapsed time. Or, err on the side of "0 seconds ago" to indicate that the fix happened in the past (and not the future).
When using the 3 fragment layout on LARGE screens, on a Galaxy Tab 7 inch display the Status fragment is cutoff and doesn't display properly. We should change to only using the 3 fragment layout on XLARGE screens instead (e.g., 10 inch tablets).
Gradle and Android Studio is the new recommended build process for Android apps, so we should switch. This would allow us to cut down on some of the bundled source that's currently included in the repo for libraries, and also allows for a simple build process with a single command, versus the Eclipse process that requires the developer to import the library projects one-by-one. Gradle also supports advanced build profiles that would allow us to compile versions without Google Play Services for F-Droid (i.e., a build that removes the map tab).
Currently, mMyLocationOverlay.runOnFirstFix() is being called on every location update in GpsMapActivity.onLocationChanged(), which then triggers a call to mMapView.getController().animateTo(). It appears that the original intent was for this animation to be triggered once at first fix, but since runOnFirstFix() is triggered on every location update, the map continuously animates to the new location every second.
Basic concept is that you hold the device up to the sky and it shows you where satellites are positioned in the actual sky, based on your orientation and position.
We can utilize the open-source Google Sky Map app to implement this.
Blog about open-sourcing the project:
http://googleresearch.blogspot.com/2012/01/open-sourcing-sky-map-and-collaborating.html?m=1
Forum post about implementation details of showing star positions:
https://groups.google.com/forum/m/#!topic/google-sky-map/UKEURYGcQP8
I'd like GPSTest to follow similar code style guidelines as Android itself:
http://source.android.com/source/code-style.html
We can use the AOSP style guide template for IntelliJ from latest Android code with Android Studio:
https://android.googlesource.com/platform/development/+/master/ide/intellij/codestyles/AndroidStyle.xml
You can drop this AndroidStyle.xml file into the Android Studio codestyles
directory, which for me is in my user preferences directory C:\Users\barbeau\.AndroidStudioPreview\config\codestyles
.
Sensor.TYPE_ORIENTATION
is deprecated. See below for details:
http://android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.html
So, we should change to the following API:
http://developer.android.com/reference/android/hardware/SensorManager.html#getOrientation%28float[],%20float%5B%5D%29
Good sample code is here:
http://www.codingforandroid.com/2011/01/using-orientation-sensors-simple.html
To provide better debugging info we should provide a display for raw NMEA data using http://developer.android.com/reference/android/location/GpsStatus.NmeaListener.html.
This should be added discretely, since most users probably won't benefit from this. Maybe in open space under the Sky view?
Obfuscation shrinks the install-size of the app, which is important since the size will increase after ActionBarSherlock and Google Play Services (via Google Maps API v2) are added.
It would be nice to have GPSTest set up with a build server, so PRs are automatically tested for build failure.
We can use Travis CI for this, which has free hosting and integration with Github:
http://docs.travis-ci.com/user/getting-started/
Stack trace:
java.lang.NullPointerException
at com.android.gpstest.GpsTestActivity.onOptionsItemSelected(Unknown Source)
at android.support.v4.app.Watson.onMenuItemSelected(Unknown Source)
at com.actionbarsherlock.a.a(Unknown Source)
at com.actionbarsherlock.internal.c.a(Unknown Source)
at com.actionbarsherlock.app.SherlockFragmentActivity.onMenuItemSelected(Unknown Source)
at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:968)
at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:149)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
at com.android.internal.view.menu.MenuPopupHelper.onItemClick(MenuPopupHelper.java:175)
at android.widget.AdapterView.performItemClick(AdapterView.java:295)
at android.widget.AbsListView.performItemClick(AbsListView.java:1073)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:2577)
at android.widget.AbsListView$1.run(AbsListView.java:3302)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4624)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
at dalvik.system.NativeStart.main(Native Method)
Looks like each menu item should have a title when using ABS, see this issue:
JakeWharton/ActionBarSherlock#902
Apparently this only affects some devices, not sure why.
User with access to QZSS Android device has provided information for the PRN range for the Japanese QZSS satellite system:
If you have an opportunity correct indications of satellites with PNR 193-202. It not GPS satellites.
link - http://www.enri.go.jp/~sakai/qzss_e.htm (table 1)
Japanese national project developing QZSS (Quasi-Zenith Satellite System)
PRN Code 193 to 202
We should update the PRN range to include QZSS support.
See conversation at:
https://groups.google.com/d/msg/gpstest_android/rRn3UChTSr4/6WQMEcL31X8J
We could add an asterisk next to the PRN in the sats list to mark GLONASS sats, and could draw the Sky view GLONASS sats as triangles instead of circles.
One item of question - is the mapping of GLONASS satellites to PRN values constant / standardized? PRN is specific to U.S. Navstar system, but a specific ID for GLONASS sats seems to be mapped to this value, based on results from Samsung Galaxy S3.
No response yet to my GIS Stack Exchange post about this.
We can move the menu controls for starting/stopping GPS and sharing location into the Action Bar.
Action Bar design patterns page, with link to download Action Bar Icon Pack:
http://developer.android.com/design/patterns/actionbar.html
Code to implement the Action Bar controls:
http://developer.android.com/guide/topics/ui/actionbar.html#ActionItems
Likely icon for location share (it's the default share icon):
We should implement this at the same time as #8 (auto-start GPS on startup), and use Pause/Play icons for stopping/starting GPS:
I updated to use Android Studio 0.6.0, which required bumping the build-tools to v19.1.0 (from v19.0.1), the Android Gradle plugin to v0.11 (from 0.9), and the Gradle wrapper to 1.12 (from 1.11).
Before the above changes, GPSTest was successfully drawing squares on a canvas to show signal strength of GLONASS satellites (see IDs 87 and 88):
After updating Android tools and launching via Android Studio or gradlew installDebug, the squares suddenly disappeared (see IDs 77, 87, 88):
Looks like Beidou PRN numbers may be 201-214, which would overlap with the ones we're currently using for QZSS (see #52). We should fix this.
See below post for details and screenshots:
https://groups.google.com/forum/#!topic/gpstest_android/rRn3UChTSr4
On large screen displays such at 10" tablets, we could easily display all three fragments (i.e., tabs, on smaller displays). A partial implementation is here:
https://github.com/barbeau/gpstest/tree/largeScreenSupport
For some reason the sensor listener is broken and the Sky view doesn't rotate properly, and isn't sized correctly to the partial screen view. So, this still needs to be fixed.
Also, we should probably provide better labeling for the Sky compass view so users understand what it is (discussed in #13), since without the "Sky" tab functionality isn't clear.
Currently, the Sky view often draws the compass off screen when the device is in a landscape orientation. We should fix this to get the proper screen height and width for just the fragment in the ViewPager.
I've tried a few implementations that try to get width and height from the Display
and DisplayMetrics
associated with the Canvas
passed into onDraw()
or the default Display from the WindowManager, and none of these seem to have any effect on this issue.
My best guess at this point is that we need to get the actual fragment height and width, with something like this:
// get the height and width of the view
mapView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
public void onGlobalLayout() {
final View v = getView();
mHeight = v.getHeight();
mWidth = v.getWidth();
// also requires width and height
enableFloors();
if (v.getViewTreeObserver().isAlive()) {
// remove this layout listener
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
v.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
} else {
v.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
}
}
});
The ROTATION_VECTOR sensor used in GPSTest for the compass that controls the rotating map and sky views points to magnetic north. We should provide an option to point the compass at true north, and provide this as the default setting since I expect most users would anticipate this as the default behavior (since satellite positions are in reference to geographic true north).
Android has a built-in utility method to do the transformation in the GeomagneticField object.
Here's a sample implementation in the Google Glass Compass Demo app:
private Location mLocation;
private GeomagneticField mGeomagneticField;
public void onLocationChanged(Location location) {
mLocation = location;
updateGeomagneticField();
notifyLocationChanged();
}
private void updateGeomagneticField() {
mGeomagneticField = new GeomagneticField((float) mLocation.getLatitude(),
(float) mLocation.getLongitude(), (float) mLocation.getAltitude(),
mLocation.getTime());
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
// Get the current heading from the sensor, then notify the listeners of the
// change.
SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X,
SensorManager.AXIS_Z, mRotationMatrix);
SensorManager.getOrientation(mRotationMatrix, mOrientation);
// Store the pitch (used to display a message indicating that the user's head
// angle is too steep to produce reliable results.
mPitch = (float) Math.toDegrees(mOrientation[1]);
// Convert the heading (which is relative to magnetic north) to one that is
// relative to true north, using the user's current location to compute this.
float magneticHeading = (float) Math.toDegrees(mOrientation[0]);
mHeading = MathUtils.mod(computeTrueNorth(magneticHeading), 360.0f)
- ARM_DISPLACEMENT_DEGREES;
notifyOrientationChanged();
}
/**
* Use the magnetic field to compute true (geographic) north from the specified heading
* relative to magnetic north.
*
* @param heading the heading (in degrees) relative to magnetic north
* @return the heading (in degrees) relative to true north
*/
private float computeTrueNorth(float heading) {
if (mGeomagneticField != null) {
return heading + mGeomagneticField.getDeclination();
} else {
return heading;
}
}
Apparently there is an issue with the getRotationMatrixFromVector() method on certain devices (especially Samsung):
java.lang.IllegalArgumentException: R array length must be 3 or 4
at android.hardware.SensorManager.getRotationMatrixFromVector(SensorManager.java:1336)
See discussion here:
https://groups.google.com/forum/#!topic/android-developers/U3N9eL5BcJk
With the ability to auto-start GPS on startup (#8), by default the "clear assistance" menu option will be disabled if we stick with the current app design. We should change this to allowing the assistance data to be cleared while GPS is on, since it may not be clear to novice users why this option is disabled by default. Also, if the user clears the assistance data while the GPS is active, we should re-register the listener via LocationManager.requestLocationUpdates() to trigger an assistance data refresh.
Currently we're filtering out all non TYPE_ROTATION_VECTOR
sensor events, which doesn't process TYPE_ORIENTATION
events.
SensorManager.getDefaultSensor()
could return null
if ROTATION_VECTOR is not supported on devices with Android 2.3 and greater, so we should check for this before trying to use the sensor.
Calling it on every location update seems to cause issues with the GPS engine (e.g., properly calculating TTFF - see Issue mikeandroid#3), and may have other undesirable consequences.
Right now satellites are shown are circles with color indicating signal level. We should also add the PRN to label which circle relates to which satellite, as well as a general "North" indicator to show which direction the user is facing. For the PRN, we could possible expand the size of the circle and render the PRN inside the circle to avoid having to deal with label placement issues, if the label was external to the circle.
After implementing #8, the GPS can now be started before the Fragments are initialized. Since the current logic for calculating the TTFF is in the GpsStatusFragment, the TTFF start time isn't recorded correctly, resulting in an incorrect TTFF value.
Now that we've gotten rid of Maps API v1 MyLocationOverlay that was causing issues with the GPSStatus.getTimeToFirstFix method (http://developer.android.com/reference/android/location/GpsStatus.html#getTimeToFirstFix()), we should try to reimplement this as the method of getting the TTFF. We need to test it with GPS Benchmark running in the background to see if the TTFF value continues to count up as it did previously when MyLocationOverlay was activated inside GPSTest.
If that doesn't work, we can look at moving the TTFF calculation into GpsTestActivity.
Introducing sensor-based orientation changes for the Maps tab produced some performance issues, so I made a change for the onOrientationChanged() method to only change the view if Fragment is visible:
ab12985
We should do the same for other methods such as onLocationChanged(), since if the Fragment isn't visible there's really no point in rendering the view.
This should result in performance improvements on small and medium screen devices that use the ViewPager, since only one fragment is visible at a time.
Currently, the app will try to continue with unexpected results, even if GPS isn't available on the device. We should inform the user that the device doesn't have GPS and gracefully exit the app.
The GPS engine can occasionally remain on after exiting the app, causing the user to have to force close it to stop the GPS. This may be due to the LocationListener being removed in GpsTestActivity.onDestroy(), which isn't guaranteed to be called in the Activity lifecycle. This should be moved to onPause(), which should be called.
With the addition of the ActionBar (#4) and auto-starting GPS on startup (#8), we should add a user tutorial to explain that GPS can now be started/stopped via the ActionBar button at the top of the screen. It should only be shown once on the first installation of the app (but accessible via Settings too).
See this StackOverflow post for options:
http://stackoverflow.com/questions/12013334/how-do-you-create-a-transparent-demo-screen-for-an-android-app
This library looks like a good option, and is similar to the tutorial shown on the Nexus in Ice Cream Sandwich:
https://github.com/Espiandev/ShowcaseView
This is disabled by default by how ABS handles GridViews. Implement ability to do this.
TabActivity has been deprecated, we should switch to using Fragments instead. Deprecated TabActivity may be causing strange behavior, such as #2.
Currently, if the user does not have GPS enabled the app just sits and doesn't show any information. On app startup, if GPS is not enabled we should ask the user if they'd like to enable GPS, and if so direct them to the system GPS Settings view.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.