From 16862f756feee75918272860a8d6492fc36e8edd Mon Sep 17 00:00:00 2001 From: dewall Date: Wed, 15 Jul 2020 15:06:47 +0200 Subject: [PATCH 1/3] reintegrated NMEA listener for Android 29 etc. --- .../app/handler/TrackRecordingHandler.java | 2 +- .../app/recording/RecordingService.java | 9 +- .../recording/provider/LocationProvider.java | 232 ++++++++++-------- 3 files changed, 135 insertions(+), 108 deletions(-) diff --git a/org.envirocar.app/src/org/envirocar/app/handler/TrackRecordingHandler.java b/org.envirocar.app/src/org/envirocar/app/handler/TrackRecordingHandler.java index 3fde82cf7..618a0ed84 100644 --- a/org.envirocar.app/src/org/envirocar/app/handler/TrackRecordingHandler.java +++ b/org.envirocar.app/src/org/envirocar/app/handler/TrackRecordingHandler.java @@ -182,7 +182,7 @@ private Single stopTrack() { LOGGER.info("Trying to stop track"); // Fire a new TrackFinishedEvent on the event bus. - mBus.post(new TrackFinishedEvent(currentTrack)); +// mBus.post(new TrackFinishedEvent(currentTrack)); LOGGER.info("posted via eventbus"); track.setTrackStatus(Track.TrackStatus.FINISHED); diff --git a/org.envirocar.app/src/org/envirocar/app/recording/RecordingService.java b/org.envirocar.app/src/org/envirocar/app/recording/RecordingService.java index 57aa28658..8d9ae5c19 100644 --- a/org.envirocar.app/src/org/envirocar/app/recording/RecordingService.java +++ b/org.envirocar.app/src/org/envirocar/app/recording/RecordingService.java @@ -137,6 +137,8 @@ public int onStartCommand(Intent intent, int flags, int startId) { .doOnDispose(() -> LOG.info("Location Provider has been disposed!")) .subscribe(() -> LOG.info("Completed"), LOG::error)); this.recordingStrategy.startRecording(this, new RecordingStrategy.RecordingListener() { + private boolean trackFinished = false; + @Override public void onRecordingStateChanged(RecordingState recordingState) { RECORDING_STATE = recordingState; @@ -149,8 +151,11 @@ public void onRecordingStateChanged(RecordingState recordingState) { @Override public void onTrackFinished(Track track) { - LOG.info("Track has been finished. Throwing TrackFinishedEvent."); - bus.post(new TrackFinishedEvent(track)); + if (!trackFinished) { + trackFinished = true; + LOG.info("Track has been finished. Throwing TrackFinishedEvent."); + bus.post(new TrackFinishedEvent(track)); + } } }); diff --git a/org.envirocar.app/src/org/envirocar/app/recording/provider/LocationProvider.java b/org.envirocar.app/src/org/envirocar/app/recording/provider/LocationProvider.java index 54c8b2593..bee88acc1 100644 --- a/org.envirocar.app/src/org/envirocar/app/recording/provider/LocationProvider.java +++ b/org.envirocar.app/src/org/envirocar/app/recording/provider/LocationProvider.java @@ -1,18 +1,18 @@ /** * Copyright (C) 2013 - 2019 the enviroCar community - * + *

* This file is part of the enviroCar app. - * + *

* The enviroCar app is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + *

* The enviroCar app is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. - * + *

* You should have received a copy of the GNU General Public License along * with the enviroCar app. If not, see http://www.gnu.org/licenses/. */ @@ -24,11 +24,11 @@ import android.location.LocationListener; import android.location.LocationManager; import android.location.OnNmeaMessageListener; +import android.os.Build; import android.os.Bundle; import com.squareup.otto.Bus; -import org.envirocar.app.handler.LocationHandler; import org.envirocar.app.recording.RecordingScope; import org.envirocar.core.events.gps.GpsDOPEvent; import org.envirocar.core.events.gps.GpsLocationChangedEvent; @@ -38,6 +38,8 @@ import org.envirocar.core.logging.Logger; import org.envirocar.core.utils.PermissionUtils; +import java.lang.reflect.Method; + import javax.inject.Inject; import io.reactivex.Completable; @@ -76,100 +78,87 @@ public void onProviderDisabled(String provider) { } }; -// /** -// * Used for receiving NMEA sentences from the GPS. -// */ -// private final OnNmeaMessageListener nmeaListener = new OnNmeaMessageListener() { -// @Override -// public void onNmeaMessage(String nmea, long timestamp) { -// -// } -// }; - -// private final GpsStatus.NmeaListener mNmeaListener = new GpsStatus.NmeaListener() { -// @Override -// public void onNmeaReceived(long timestamp, String nmea) { -// // eg2.: $GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*35 -// if (nmea.startsWith(GPGSA)) { -// boolean fix = true; -// if (nmea.charAt(7) == ',' || nmea.charAt(9) == '1') { -// fix = false; // no GPS fix, skip. -// } -// -// int checksumIndex = nmea.lastIndexOf("*"); -// String[] values; -// if (checksumIndex > 0) { -// values = nmea.substring(0, checksumIndex).split(NMEA_SEP); -// } else { -// return; // no checksum, skip. -// } -// -// int numberOfSats = resolveSatelliteCount(values); -// -// // fire an event on the GPS status (fix and number of sats) -// mBus.post(new GpsSatelliteFixEvent(numberOfSats, fix)); -// -// Double pdop = null, hdop = null, vdop = null; -// if (values.length > 15) { -// pdop = parseDopString(values[15]); -// } -// if (values.length > 16) { -// hdop = parseDopString(values[16]); -// } -// if (values.length > 17) { -// vdop = parseDopString(values[17]); -// } -// -// // Only if positional, horizontal, and vertical DOP is available, then -// // set the DOP accordingly. -// if (pdop != null || hdop != null || vdop != null) { -// // Dultion of Precision (DOP) to specify multiplicative effect of -// // navigation satellite geometry on positional measurement precision. -// // fire an event on the GPS DOP -// mBus.post(new GpsDOPEvent(pdop, hdop, vdop)); -// } -// } -// } -// -// /** -// * Resolves the number of satellites. -// * -// * @param values -// * @return number of satellites. -// */ -// private int resolveSatelliteCount(String[] values) { -// if (values == null || values.length < 3) { -// return 0; -// } -// -// int result = 0; -// for (int i = 3; i < 15; i++) { -// if (i > values.length - 1) { -// break; -// } -// -// if (!values[i].trim().isEmpty()) { -// result++; -// } -// } -// return result; -// } -// -// /** -// * -// * @param string -// * @return -// */ -// private Double parseDopString(String string) { -// if (string == null || string.isEmpty()) return null; -// try { -// return Double.parseDouble(string.trim()); -// } catch (RuntimeException e) { -// // TODO no exception catching? -// } -// return null; -// } -// }; + + private void onNewNmeaUpdate(String nmea, long timestamp) { + // eg2.: $GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*35 + if (nmea.startsWith(GPGSA)) { + boolean fix = true; + if (nmea.charAt(7) == ',' || nmea.charAt(9) == '1') { + fix = false; // no GPS fix, skip. + } + + int checksumIndex = nmea.lastIndexOf("*"); + String[] values; + if (checksumIndex > 0) { + values = nmea.substring(0, checksumIndex).split(NMEA_SEP); + } else { + return; // no checksum, skip. + } + + int numberOfSats = resolveSatelliteCount(values); + + // fire an event on the GPS status (fix and number of sats) + mBus.post(new GpsSatelliteFixEvent(numberOfSats, fix)); + + Double pdop = null, hdop = null, vdop = null; + if (values.length > 15) { + pdop = parseDopString(values[15]); + } + if (values.length > 16) { + hdop = parseDopString(values[16]); + } + if (values.length > 17) { + vdop = parseDopString(values[17]); + } + + // Only if positional, horizontal, and vertical DOP is available, then + // set the DOP accordingly. + if (pdop != null || hdop != null || vdop != null) { + // Dultion of Precision (DOP) to specify multiplicative effect of + // navigation satellite geometry on positional measurement precision. + // fire an event on the GPS DOP + mBus.post(new GpsDOPEvent(pdop, hdop, vdop)); + } + } + } + + /** + * Resolves the number of satellites. + * + * @param values + * @return number of satellites. + */ + private int resolveSatelliteCount(String[] values) { + if (values == null || values.length < 3) { + return 0; + } + + int result = 0; + for (int i = 3; i < 15; i++) { + if (i > values.length - 1) { + break; + } + + if (!values[i].trim().isEmpty()) { + result++; + } + } + return result; + } + + /** + * @param string + * @return + */ + private Double parseDopString(String string) { + if (string == null || string.isEmpty()) return null; + try { + return Double.parseDouble(string.trim()); + } catch (RuntimeException e) { + // TODO no exception catching? + } + return null; + } // Injected variables. private final Context mContext; @@ -180,6 +169,8 @@ public void onProviderDisabled(String provider) { // Location fields private Location mLastBestLocation; + private Method oldAddNmeaMethod; + /** * Constructor. * @@ -207,13 +198,44 @@ public Completable startLocating() { emitter.onError(new PermissionException("User has not activated Location permission")); mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener); -// mLocationManager.addNmeaListener(mNmeaListener); - emitter.setCancellable(() -> { - LOGGER.info("stopLocating()"); - mLocationManager.removeUpdates(mLocationListener); -// mLocationManager.removeNmeaListener(mNmeaListener); - }); + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + final OnNmeaMessageListener nmeaListener = (nmea, timestamp) -> onNewNmeaUpdate(nmea, timestamp); + mLocationManager.addNmeaListener(nmeaListener); + + emitter.setCancellable(() -> { + LOGGER.info("stopLocating()"); + mLocationManager.removeUpdates(mLocationListener); + mLocationManager.removeNmeaListener(nmeaListener); + }); + } else { + final GpsStatus.NmeaListener nmeaListener = (timestamp, nmea) -> onNewNmeaUpdate(nmea, timestamp); + + // get the old add nmea method via reflection. + if (oldAddNmeaMethod == null) { + oldAddNmeaMethod = LocationManager.class.getMethod("addNmeaListener", GpsStatus.NmeaListener.class); + } + oldAddNmeaMethod.invoke(mLocationManager, nmeaListener); + emitter.setCancellable(() -> { + LOGGER.info("stopLocating()"); + mLocationManager.removeUpdates(mLocationListener); + + try { + Method oldRemoveNmeaMethod = LocationManager.class.getMethod("removeNmeaListener", GpsStatus.NmeaListener.class); + oldRemoveNmeaMethod.invoke(mLocationManager, nmeaListener); + } catch (Exception e){ + LOGGER.error("unable to remove nmea listener", e); + } + }); + } + } catch (Exception e) { + LOGGER.error("Error while initiating NMEA Listener"); + emitter.setCancellable(() -> { + LOGGER.info("stopLocating()"); + mLocationManager.removeUpdates(mLocationListener); + }); + } }); } } From 0e93f2b8b53af264579384b3f0ed2923f18bb436 Mon Sep 17 00:00:00 2001 From: dewall Date: Wed, 15 Jul 2020 15:12:05 +0200 Subject: [PATCH 2/3] increased version for release --- build.gradle | 4 ++-- org.envirocar.app/AndroidManifest.xml | 4 ++-- .../envirocar/app/recording/provider/LocationProvider.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index ff1e42be0..1e4726ae3 100644 --- a/build.gradle +++ b/build.gradle @@ -50,8 +50,8 @@ ext { compileSdkVersion = 29 targetSdkVersion = 29 buildToolsVersion = '29.0.2' - versionCode = 48 - versionName = "1.1.8" + versionCode = 49 + versionName = "1.1.9" javaCompileVersion = JavaVersion.VERSION_1_8 diff --git a/org.envirocar.app/AndroidManifest.xml b/org.envirocar.app/AndroidManifest.xml index 05d2d4d3f..45b76e88b 100644 --- a/org.envirocar.app/AndroidManifest.xml +++ b/org.envirocar.app/AndroidManifest.xml @@ -3,8 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" package="org.envirocar.app" android:installLocation="internalOnly" - android:versionCode="48" - android:versionName="1.1.8"> + android:versionCode="49" + android:versionName="1.1.9"> diff --git a/org.envirocar.app/src/org/envirocar/app/recording/provider/LocationProvider.java b/org.envirocar.app/src/org/envirocar/app/recording/provider/LocationProvider.java index bee88acc1..8bbd2cc62 100644 --- a/org.envirocar.app/src/org/envirocar/app/recording/provider/LocationProvider.java +++ b/org.envirocar.app/src/org/envirocar/app/recording/provider/LocationProvider.java @@ -230,7 +230,7 @@ public Completable startLocating() { }); } } catch (Exception e) { - LOGGER.error("Error while initiating NMEA Listener"); + LOGGER.error("Error while initiating NMEA Listener", e); emitter.setCancellable(() -> { LOGGER.info("stopLocating()"); mLocationManager.removeUpdates(mLocationListener); From f7a98c7a6b2a36e78b937ddaee3f9f874d9a8e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Pro=C3=9F?= Date: Wed, 15 Jul 2020 16:03:49 +0200 Subject: [PATCH 3/3] Allow colon for estimated time of log reports --- .../res/layout/send_log_layout_new.xml | 2 +- org.envirocar.app/res/values/strings.xml | 4 +-- .../app/views/others/SendLogFileActivity.java | 29 +++++++++++++------ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/org.envirocar.app/res/layout/send_log_layout_new.xml b/org.envirocar.app/res/layout/send_log_layout_new.xml index 9ed6a3542..a4ce37160 100644 --- a/org.envirocar.app/res/layout/send_log_layout_new.xml +++ b/org.envirocar.app/res/layout/send_log_layout_new.xml @@ -82,7 +82,7 @@ android:layout_height="wrap_content" android:gravity="start|top" android:imeOptions="actionNext" - android:inputType="number" + android:inputType="date|time" android:padding="12dp" /> diff --git a/org.envirocar.app/res/values/strings.xml b/org.envirocar.app/res/values/strings.xml index 3109359fb..27d2d629e 100644 --- a/org.envirocar.app/res/values/strings.xml +++ b/org.envirocar.app/res/values/strings.xml @@ -106,8 +106,8 @@ Report an Issue Summary of what went wrong - Time since crash: - in minutes + Estimated time + 10:00 No Checkbox Selected You have not selected any of the checkboxes. These help developers sort through issues quickly and resolve them. Please consider filling those that are relevant. diff --git a/org.envirocar.app/src/org/envirocar/app/views/others/SendLogFileActivity.java b/org.envirocar.app/src/org/envirocar/app/views/others/SendLogFileActivity.java index 20577726e..c818431b2 100644 --- a/org.envirocar.app/src/org/envirocar/app/views/others/SendLogFileActivity.java +++ b/org.envirocar.app/src/org/envirocar/app/views/others/SendLogFileActivity.java @@ -57,9 +57,11 @@ import java.io.FileFilter; import java.io.IOException; import java.text.DateFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; @@ -312,7 +314,7 @@ private String createComments() { } private String createEstimatedTimeStamp() { - long now = System.currentTimeMillis(); + String text; try { text = whenField.getText().toString(); @@ -321,15 +323,24 @@ private String createEstimatedTimeStamp() { text = null; } - int delta; - if (text == null || text.isEmpty()) { - delta = 0; - } else { - delta = Integer.parseInt(text); - } + String[] hoursAndMinutes = text.split(":"); - Date date = new Date(now - delta * 1000 * 60); - return SimpleDateFormat.getDateTimeInstance().format(date); + Calendar calendar = Calendar.getInstance(); + + if(hoursAndMinutes.length > 1){ + try { + calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hoursAndMinutes[0])); + } catch (Exception e) { + LOG.info("Could not parse hour of day."); + } + + try { + calendar.set(Calendar.MINUTE, Integer.parseInt(hoursAndMinutes[1])); + } catch (Exception e) { + LOG.info("Could not parse minute."); + } + } + return SimpleDateFormat.getDateTimeInstance().format(calendar.getTime()); }