diff --git a/res/drawable-xxhdpi/solution_fix.png b/res/drawable-xxhdpi/solution_fix.png new file mode 100644 index 00000000..ad889c30 Binary files /dev/null and b/res/drawable-xxhdpi/solution_fix.png differ diff --git a/res/drawable-xxhdpi/solution_float.png b/res/drawable-xxhdpi/solution_float.png new file mode 100644 index 00000000..f1cf19fb Binary files /dev/null and b/res/drawable-xxhdpi/solution_float.png differ diff --git a/res/drawable-xxhdpi/solution_none.png b/res/drawable-xxhdpi/solution_none.png new file mode 100644 index 00000000..a151b4a3 Binary files /dev/null and b/res/drawable-xxhdpi/solution_none.png differ diff --git a/res/drawable-xxhdpi/solution_single.png b/res/drawable-xxhdpi/solution_single.png new file mode 100644 index 00000000..ab8c983d Binary files /dev/null and b/res/drawable-xxhdpi/solution_single.png differ diff --git a/res/values/strings.xml b/res/values/strings.xml index b6a5210b..ae03deac 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -29,6 +29,7 @@ Geoportail aerial Local service started Local service stopped + %s since %s RtkGps N W @@ -52,7 +53,7 @@ Processing options Solution options Caster options - + Rover Base @@ -130,7 +131,7 @@ b: height: - + Single DGPS/DGNSS @@ -168,7 +169,7 @@ PPP Dead reckoning Internal - + Lat/Long/Height X/Y/Z — ECEF @@ -261,7 +262,7 @@ Rinex header RTCM Antenna position - + Processing options 1 Solution options @@ -327,7 +328,7 @@ 35 40 - + GPS Integer ambiguity resolution GPS Integer ambiguity resolution @@ -532,11 +533,11 @@ 30 60 - + Output header Set whether the header is output or not - + Output GPS mock locations Set if solution is sent to other applications like the internal GPS @@ -553,7 +554,7 @@ OFF Solid Solid, ocean, pole - + ddd.dddddddd : Degree ddd mm ss.sss : Degree minute second @@ -627,7 +628,7 @@ +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs Enable test mode If this is enabled and Rover/Base/Correction are off, it runs in a special test mode with positions coming from internal GPS. Obviously no algorithm from RTKLIB can work - + Type Format @@ -644,10 +645,10 @@ Receiver option Transmit GPGGA to Base Station Latitude - Longitude + Longitude Antenna Antenna official IGS name (for phase center variation) - + OFF Latitude/Longitude @@ -658,8 +659,8 @@ 1 2 - - + + Enable Solution 1 Enable Solution 2 @@ -668,7 +669,7 @@ Solution 2 GPX Trace - + Log rover Log base @@ -676,7 +677,7 @@ Log Rover Log Base Log Correction - + NTRIP client settings Host @@ -703,7 +704,7 @@ File settings - + Bluetooth receiver settings device not selected @@ -711,7 +712,7 @@ Bluetooth device Bluetooth system settings Display system Bluetooth settings screen - + Bluetooth connected Bluetooth connection lost @@ -744,10 +745,10 @@ - + USB connected USB connection lost - + USB receiver settings Baudrate @@ -794,7 +795,7 @@ 1 2 - + Send commands at startup Send commands at shutdown @@ -802,14 +803,14 @@ Commands at shutdown Load Select file - + Lat/Lon/Height (deg/m) Lat/Lon/Height (dms/m) X/Y/Z — ECEF For fixed mode For relative mode - + SNR Rover/Base SNR Rover/Base L1 @@ -817,7 +818,7 @@ SNR Rover/Base L5 Skyplot Rover L1 Skyplot Rover L2 - Skyplot Rover L5 + Skyplot Rover L5 Skyplot Base L1 Skyplot Base L2 Skyplot Base L5 @@ -830,12 +831,12 @@ Install EGM 2008 2.5\' Geoid (135MB) Install EGM 2008 1.0\' Geoid (825MB) Install EGM 96 15\' Geoid (2MB) - + Change Log What\'s New OK more… - + Enable experimental NTRIP Caster NTRIP Caster Ending NTRIP Caster will also shutown RTKGPS+, it is safer for being sure all connections are closed. diff --git a/src/gpsplus/rtkgps/RtkNaviService.java b/src/gpsplus/rtkgps/RtkNaviService.java index 864d73ad..9940368b 100644 --- a/src/gpsplus/rtkgps/RtkNaviService.java +++ b/src/gpsplus/rtkgps/RtkNaviService.java @@ -23,6 +23,7 @@ import android.provider.Settings; import android.support.v4.app.ActivityCompat; import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationManagerCompat; import android.util.Log; import android.widget.Toast; import butterknife.BindString; @@ -62,6 +63,7 @@ import gpsplus.rtklib.Solution; import gpsplus.rtklib.constants.EphemerisOption; import gpsplus.rtklib.constants.GeoidModel; +import gpsplus.rtklib.constants.SolutionStatus; import gpsplus.rtklib.constants.StreamType; import java.io.BufferedWriter; @@ -69,6 +71,8 @@ import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Method; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.Locale; public class RtkNaviService extends IntentService implements LocationListener { @@ -131,7 +135,12 @@ public RtkNaviService() { private static final String MM_MAP_HEADER = "COMPD_CS[\"WGS 84\",GEOGCS[\"\",DATUM[\"WGS 84\",SPHEROID[\"WGS 84\",6378137,298.257223563],TOWGS84[0,0,0,0,0,0,0]],PRIMEM[\"Greenwich\",0],UNIT[\"Degrees\",0.0174532925199433],AXIS[\"Long\",East],AXIS[\"Lat\",North]],VERT_CS[\"\",VERT_DATUM[\"Ellipsoid\",2002],UNIT[\"Meters\",1],AXIS[\"Height\",Up]]]\r\n"; private static final String GPS_PROVIDER = LocationManager.GPS_PROVIDER; private boolean mHavePoint = false; - private int NOTIFICATION = R.string.local_service_started; + private static final int NOTIFICATION = R.string.local_service_started; + private static NotificationCompat.Builder notificationBuilder; + private static NotificationManagerCompat notificationManager; + private static SolutionStatus previousSolutionStatus; + private static Context context; + private RtkCommon rtkCommon; // Binder given to clients @@ -160,10 +169,10 @@ public RtkNaviService() { @Override public void onCreate() { super.onCreate(); + context = this.getBaseContext(); final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); mCpuLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); - } @Override @@ -389,8 +398,11 @@ public void processStart() { mCpuLock.acquire(); - Notification notification = createForegroundNotification(); - startForeground(NOTIFICATION, notification); + notificationManager = NotificationManagerCompat.from(this); + notificationBuilder = createForegroundNotificationBuilder(); + previousSolutionStatus = SolutionStatus.NONE; + setNotificationSolutionStatus(previousSolutionStatus); + startForeground(NOTIFICATION, notificationBuilder.build()); SharedPreferences prefs = this.getBaseContext().getSharedPreferences(SolutionOutputSettingsFragment.SHARED_PREFS_NAME, 0); mBoolMockLocationsPref = prefs.getBoolean(SolutionOutputSettingsFragment.KEY_OUTPUT_MOCK_LOCATION, false); @@ -437,7 +449,6 @@ public void processStart() { mBoolIsRunning = true; } - private void processStop() { mBoolIsRunning = false; mbStarted = false; @@ -628,7 +639,7 @@ public void onDestroy() { } @SuppressWarnings("deprecation") - private Notification createForegroundNotification() { + private NotificationCompat.Builder createForegroundNotificationBuilder() { CharSequence text = getText(R.string.local_service_started); // The PendingIntent to launch our activity if the user selects this @@ -645,7 +656,7 @@ private Notification createForegroundNotification() { builder.setNumber(100); builder.setAutoCancel(false); - return builder.build(); + return builder; } private class BluetoothCallbacks implements BluetoothToRtklib.Callbacks { @@ -831,6 +842,34 @@ private void stopUsb() { } } + private static void setNotificationSolutionStatus(SolutionStatus solutionStatus) { + int resId = solutionStatus.getNameResId(); + String solutionStatusText = context.getString(resId); + String contentText = String.format( + context.getString(R.string.local_service_notification_content), + solutionStatusText, + new SimpleDateFormat("HH:mm:ss").format(new Date()) + ); + notificationBuilder.setContentText(contentText); + notificationBuilder.setSmallIcon(solutionStatus.getIconResId()); + } + + private static void updateNotification() { + notificationManager.notify(NOTIFICATION, notificationBuilder.build()); + } + + public static void setNotificationSolutionStatusWithUpdate(SolutionStatus solutionStatus) { + if ( + previousSolutionStatus != solutionStatus && + notificationBuilder != null && + notificationManager != null + ) { + setNotificationSolutionStatus(solutionStatus); + updateNotification(); + previousSolutionStatus = solutionStatus; + } + } + /* (non-Javadoc) * @see android.app.IntentService#onHandleIntent(android.content.Intent) */ @@ -842,10 +881,12 @@ protected void onHandleIntent(Intent arg0) { { try { + RtkControlResult result = getRtkStatus(null); + Solution solution = result.getSolution(); + SolutionStatus solutionStatus = solution.getSolutionStatus(); + setNotificationSolutionStatusWithUpdate(solutionStatus); if (mBoolMockLocationsPref || mBoolGenerateGPXTrace) { - RtkControlResult result = getRtkStatus(null); - Solution solution = result.getSolution(); Position3d positionECEF = solution.getPosition(); if (RtkCommon.norm(positionECEF.getValues()) > 0.0) diff --git a/src/gpsplus/rtkgps/view/SolutionView.java b/src/gpsplus/rtkgps/view/SolutionView.java index 51965d11..39e05238 100644 --- a/src/gpsplus/rtkgps/view/SolutionView.java +++ b/src/gpsplus/rtkgps/view/SolutionView.java @@ -275,6 +275,7 @@ public void setStats(RtkControlResult status) { mSolutionIndicatorView.setStatus(solStatus); updateCoordinates(status); updateAgeText(sol); + RtkNaviService.setNotificationSolutionStatusWithUpdate(solStatus); } public void setFormat(Format format) { diff --git a/src/gpsplus/rtklib/constants/SolutionStatus.java b/src/gpsplus/rtklib/constants/SolutionStatus.java index e3e19e1a..341d4d17 100644 --- a/src/gpsplus/rtklib/constants/SolutionStatus.java +++ b/src/gpsplus/rtklib/constants/SolutionStatus.java @@ -10,23 +10,25 @@ */ public enum SolutionStatus implements IHasRtklibId { - NONE(0, R.string.solq_none), - FIX(1, R.string.solq_fix), - FLOAT(2, R.string.solq_float), - SBAS(3, R.string.solq_sbas), - DGPS(4, R.string.solq_dgps), - SINGLE(5, R.string.solq_single), - PPP(6, R.string.solq_ppp), - DR(7, R.string.solq_dr), - INTERNAL(8,R.string.solq_internal) + NONE(0, R.string.solq_none, R.drawable.solution_none), + FIX(1, R.string.solq_fix, R.drawable.solution_fix), + FLOAT(2, R.string.solq_float, R.drawable.solution_float), + SBAS(3, R.string.solq_sbas, R.drawable.solution_single), + DGPS(4, R.string.solq_dgps, R.drawable.solution_single), + SINGLE(5, R.string.solq_single, R.drawable.solution_single), + PPP(6, R.string.solq_ppp, R.drawable.solution_fix), + DR(7, R.string.solq_dr, R.drawable.solution_none), + INTERNAL(8, R.string.solq_internal, R.drawable.solution_single) ; private final int mRtklibId; private final int mNameResId; + private final int mIconResId; - private SolutionStatus(int solqId, int nameResId) { + private SolutionStatus(int solqId, int nameResId, int iconResId) { mRtklibId = solqId; mNameResId = nameResId; + mIconResId = iconResId; } public static SolutionStatus valueOf(int solqId) { @@ -47,4 +49,8 @@ public int getRtklibId() { public int getNameResId() { return mNameResId; } + + public int getIconResId() { + return mIconResId; + } };