From 01c95079db466b7715e30d742cf5a83d8b753462 Mon Sep 17 00:00:00 2001 From: Gerhard Olsson <6248932+gerhardol@users.noreply.github.com> Date: Tue, 30 Dec 2025 11:31:13 +0100 Subject: [PATCH 1/6] fix: logging level cleanup (#1259) Decrease logging level for many entries. Many normal events were using Log.e() --- .../runnerup/content/ActivityProvider.java | 14 +++++----- .../main/org/runnerup/db/ActivityCleaner.java | 2 +- app/src/main/org/runnerup/db/DBHelper.java | 10 +++---- .../runnerup/export/DefaultSynchronizer.java | 4 +-- .../org/runnerup/export/FileSynchronizer.java | 4 +-- .../export/RunKeeperSynchronizer.java | 2 +- .../export/RunningAHEADSynchronizer.java | 4 +-- .../main/org/runnerup/export/SyncManager.java | 12 ++++---- .../export/oauth2client/OAuth2Activity.java | 2 +- .../main/org/runnerup/tracker/Tracker.java | 8 +++--- .../component/TrackerComponentCollection.java | 10 +++---- .../tracker/component/TrackerElevation.java | 2 +- app/src/main/org/runnerup/util/Formatter.java | 2 +- .../main/org/runnerup/util/GraphWrapper.java | 28 +++++++++---------- app/src/main/org/runnerup/util/HRZones.java | 8 +++--- .../org/runnerup/view/DetailActivity.java | 2 +- .../org/runnerup/view/HRZonesActivity.java | 9 +++--- .../main/org/runnerup/view/HRZonesBar.java | 2 +- .../main/org/runnerup/view/MainLayout.java | 12 ++++---- .../org/runnerup/view/ManualActivity.java | 8 +++--- .../main/org/runnerup/view/RunActivity.java | 2 +- .../main/org/runnerup/view/StartFragment.java | 14 +++++----- .../runnerup/workout/EndOfLapSuppression.java | 2 +- .../org/runnerup/workout/TargetTrigger.java | 7 ++--- .../main/org/runnerup/workout/Trigger.java | 2 +- .../org/runnerup/workout/WorkoutBuilder.java | 2 +- .../runnerup/workout/WorkoutSerializer.java | 4 +-- .../workout/feedback/RUTextToSpeech.java | 10 +++---- .../tracker/component/TrackerWear.java | 12 ++++---- hrdevice/src/org/runnerup/hr/Bt20Base.java | 4 ++- hrdevice/src/org/runnerup/hr/BtHRBase.java | 4 ++- hrdevice/src/org/runnerup/hr/HRManager.java | 2 +- .../runnerup/hr/RetryingHRProviderProxy.java | 4 ++- .../org/runnerup/service/ListenerService.java | 18 ++++++------ .../org/runnerup/service/StateService.java | 14 ++++++---- .../java/org/runnerup/view/MainActivity.java | 9 +++--- 36 files changed, 133 insertions(+), 122 deletions(-) diff --git a/app/src/main/org/runnerup/content/ActivityProvider.java b/app/src/main/org/runnerup/content/ActivityProvider.java index 159d1d960..d7fbad76b 100644 --- a/app/src/main/org/runnerup/content/ActivityProvider.java +++ b/app/src/main/org/runnerup/content/ActivityProvider.java @@ -97,7 +97,7 @@ private Pair openCacheFile(String name) { @SuppressWarnings("ConstantConditions") final File file = new File(path.getAbsolutePath() + File.separator + name); final OutputStream out = new BufferedOutputStream(new FileOutputStream(file)); - Log.e(getClass().getName(), i + ": putting cache file in: " + file.getAbsolutePath()); + Log.d(getClass().getName(), i + ": putting cache file in: " + file.getAbsolutePath()); //noinspection Convert2Diamond return new Pair(file, out); } catch (IOException | NullPointerException ignored) { @@ -112,7 +112,7 @@ public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException { final int res = uriMatcher.match(uri); - Log.e(getClass().getName(), "match(" + uri + "): " + res); + Log.d(getClass().getName(), "match(" + uri + "): " + res); switch (res) { case GPX: case TCX: @@ -122,11 +122,11 @@ public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) final String parcelFile = "activity." + list.get(list.size() - 3); final Pair out = openCacheFile(parcelFile); if (out == null) { - Log.e(getClass().getName(), "Failed to open cacheFile(" + parcelFile + ")"); + Log.i(getClass().getName(), "Failed to open cacheFile(" + parcelFile + ")"); return null; } - Log.e( + Log.d( getClass().getName(), "activity: " + activityId + ", file: " + out.first.getAbsolutePath()); SQLiteDatabase mDB = DBHelper.getReadableDatabase(getContext()); @@ -139,7 +139,7 @@ public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) var options = ExportOptions.builder(); TCX tcx = new TCX(mDB, options.build(), simplifier); tcx.export(activityId, new OutputStreamWriter(out.second)); - Log.e(getClass().getName(), "export tcx"); + Log.d(getClass().getName(), "export tcx"); break; } case GPX:{ @@ -154,13 +154,13 @@ public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) options.accuracyExtensions = extraData; GPX gpx = new GPX(mDB, options.build(), simplifier); gpx.export(activityId, new OutputStreamWriter(out.second)); - Log.e(getClass().getName(), "export gpx"); + Log.d(getClass().getName(), "export gpx"); break; } } out.second.flush(); out.second.close(); - Log.e(getClass().getName(), "wrote " + out.first.length() + " bytes..."); + Log.d(getClass().getName(), "wrote " + out.first.length() + " bytes..."); } catch (Exception e) { e.printStackTrace(); } diff --git a/app/src/main/org/runnerup/db/ActivityCleaner.java b/app/src/main/org/runnerup/db/ActivityCleaner.java index 62d3b04b0..38e0d37b6 100644 --- a/app/src/main/org/runnerup/db/ActivityCleaner.java +++ b/app/src/main/org/runnerup/db/ActivityCleaner.java @@ -230,7 +230,7 @@ public static void trim(SQLiteDatabase db, long activityId) { for (long lap : laps) { int res = trimLap(db, activityId, lap); - Log.e("ActivityCleaner", "lap " + lap + " removed " + res + " locations"); + Log.i("ActivityCleaner", "lap " + lap + " removed " + res + " locations"); } } diff --git a/app/src/main/org/runnerup/db/DBHelper.java b/app/src/main/org/runnerup/db/DBHelper.java index d529f4df8..df480de72 100644 --- a/app/src/main/org/runnerup/db/DBHelper.java +++ b/app/src/main/org/runnerup/db/DBHelper.java @@ -260,7 +260,7 @@ public void onCreate(SQLiteDatabase arg0) { @Override public void onUpgrade(SQLiteDatabase arg0, int oldVersion, int newVersion) { - Log.e( + Log.i( getClass().getName(), "onUpgrade: oldVersion: " + oldVersion + ", newVersion: " + newVersion); @@ -429,7 +429,7 @@ private void onCreateUpgrade(SQLiteDatabase arg0, int oldVersion, int newVersion } private static void echoDo(SQLiteDatabase arg0, String str) { - Log.e("DBHelper", "execSQL(" + str + ")"); + Log.d("DBHelper", "execSQL(" + str + ")"); arg0.execSQL(str); } @@ -567,12 +567,12 @@ private static void insertAccount(SQLiteDatabase arg0, String name, int enabled, arg1.remove(DB.ACCOUNT.FORMAT); arg1.remove(DB.ACCOUNT.AUTH_METHOD); arg0.update(DB.ACCOUNT.TABLE, arg1, DB.ACCOUNT.NAME + " = ?", arr); - Log.v("DBhelper", "update: " + arg1); + Log.d("DBhelper", "update: " + arg1); } } public static void deleteAccount(SQLiteDatabase db, long id) { - Log.e("DBHelper", "deleting account: " + id); + Log.v("DBHelper", "deleting account: " + id); String[] args = {Long.toString(id)}; db.delete(DB.EXPORT.TABLE, DB.EXPORT.ACCOUNT + " = ?", args); db.delete(DB.ACCOUNT.TABLE, "_id = ?", args); @@ -601,7 +601,7 @@ public static ContentValues[] toArray(Cursor c) { } public static void deleteActivity(SQLiteDatabase db, long id) { - Log.e("DBHelper", "deleting activity: " + id); + Log.v("DBHelper", "deleting activity: " + id); String[] args = {Long.toString(id)}; db.delete(DB.EXPORT.TABLE, DB.EXPORT.ACTIVITY + " = ?", args); db.delete(DB.LOCATION.TABLE, DB.LOCATION.ACTIVITY + " = ?", args); diff --git a/app/src/main/org/runnerup/export/DefaultSynchronizer.java b/app/src/main/org/runnerup/export/DefaultSynchronizer.java index 734306ce6..2ec40ca9a 100644 --- a/app/src/main/org/runnerup/export/DefaultSynchronizer.java +++ b/app/src/main/org/runnerup/export/DefaultSynchronizer.java @@ -98,7 +98,7 @@ public void init(ContentValues config) { @NonNull @Override public Intent getAuthIntent(AppCompatActivity a) { - Log.e(getName(), "getAuthIntent: getAuthIntent must be implemented for OAUTH2"); + Log.i(getName(), "getAuthIntent: getAuthIntent must be implemented for OAUTH2"); return new Intent(); } @@ -158,7 +158,7 @@ public final Status download(SQLiteDatabase db, SyncActivityItem item) { } ActivityEntity download(SyncActivityItem item) { - Log.e(Constants.LOG, "No download method implemented for the synchronizer " + getName()); + Log.i(Constants.LOG, "No download method implemented for the synchronizer " + getName()); return null; } diff --git a/app/src/main/org/runnerup/export/FileSynchronizer.java b/app/src/main/org/runnerup/export/FileSynchronizer.java index b1cd3f322..91ef1a0b0 100644 --- a/app/src/main/org/runnerup/export/FileSynchronizer.java +++ b/app/src/main/org/runnerup/export/FileSynchronizer.java @@ -258,7 +258,7 @@ private OutputStream getOutputStream(String fileName, String mimeType) throws IO final Uri contentUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); Uri uri = resolver.insert(contentUri, contentValues); if (uri == null) { - Log.w(getName(), "No uri: " + contentUri + " " + fileName); + Log.i(getName(), "No uri: " + contentUri + " " + fileName); return null; } return resolver.openOutputStream(uri); @@ -266,7 +266,7 @@ private OutputStream getOutputStream(String fileName, String mimeType) throws IO String path = new File(mPath).getAbsolutePath() + File.separator + fileName; if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - Log.w(getName(), "No permission to write to: " + path); + Log.i(getName(), "No permission to write to: " + path); return null; } File file = new File(path); diff --git a/app/src/main/org/runnerup/export/RunKeeperSynchronizer.java b/app/src/main/org/runnerup/export/RunKeeperSynchronizer.java index 6be182239..bff3afc69 100644 --- a/app/src/main/org/runnerup/export/RunKeeperSynchronizer.java +++ b/app/src/main/org/runnerup/export/RunKeeperSynchronizer.java @@ -411,7 +411,7 @@ public Status upload(SQLiteDatabase db, final long mID) { Exception ex; try { URL newurl = new URL(REST_URL + fitnessActivitiesUrl); - // Log.e(Constants.LOG, "url: " + newurl.toString()); + // Log.d(Constants.LOG, "url: " + newurl.toString()); conn = (HttpURLConnection) newurl.openConnection(); conn.setDoOutput(true); conn.setRequestMethod(RequestMethod.POST.name()); diff --git a/app/src/main/org/runnerup/export/RunningAHEADSynchronizer.java b/app/src/main/org/runnerup/export/RunningAHEADSynchronizer.java index 5e6e0b193..31ff66a22 100644 --- a/app/src/main/org/runnerup/export/RunningAHEADSynchronizer.java +++ b/app/src/main/org/runnerup/export/RunningAHEADSynchronizer.java @@ -232,7 +232,7 @@ public Status upload(SQLiteDatabase db, final long mID) { out.close(); int responseCode = conn.getResponseCode(); String amsg = conn.getResponseMessage(); - Log.e(getName(), "code: " + responseCode + ", amsg: " + amsg); + Log.d(getName(), "code: " + responseCode + ", amsg: " + amsg); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); JSONObject obj = SyncHelper.parse(in); @@ -252,7 +252,7 @@ public Status upload(SQLiteDatabase db, final long mID) { } } if (!found) { - Log.e(getName(), "Unhandled response from RunningAHEADSynchronizer: " + obj); + Log.i(getName(), "Unhandled response from RunningAHEADSynchronizer: " + obj); } if (responseCode == HttpURLConnection.HTTP_OK && found) { conn.disconnect(); diff --git a/app/src/main/org/runnerup/export/SyncManager.java b/app/src/main/org/runnerup/export/SyncManager.java index f669b6f26..2e7ffd033 100644 --- a/app/src/main/org/runnerup/export/SyncManager.java +++ b/app/src/main/org/runnerup/export/SyncManager.java @@ -160,7 +160,7 @@ public long load(String synchronizerName) { @SuppressWarnings("null") public Synchronizer add(ContentValues config) { if (config == null) { - Log.e(getClass().getName(), "Add null!"); + Log.w(getClass().getName(), "Add null!"); if (BuildConfig.DEBUG) { throw new AssertionError(); } @@ -169,7 +169,7 @@ public Synchronizer add(ContentValues config) { String synchronizerName = config.getAsString(DB.ACCOUNT.NAME); if (synchronizerName == null) { - Log.e(getClass().getName(), "name not found!"); + Log.w(getClass().getName(), "name not found!"); return null; } if (synchronizers.containsKey(synchronizerName)) { @@ -196,7 +196,7 @@ public Synchronizer add(ContentValues config) { } else if (synchronizerName.contentEquals(EndurainSynchronizer.NAME)) { synchronizer = new EndurainSynchronizer(simplifier); } else { - Log.e(getClass().getName(), "synchronizer does not exist: " + synchronizerName); + Log.w(getClass().getName(), "synchronizer does not exist: " + synchronizerName); } if (synchronizer != null) { @@ -209,7 +209,7 @@ public Synchronizer add(ContentValues config) { synchronizers.put(synchronizerName, synchronizer); synchronizersById.put(synchronizer.getId(), synchronizer); } else { - Log.e(getClass().getName(), "Synchronizer not found for " + synchronizerName); + Log.w(getClass().getName(), "Synchronizer not found for " + synchronizerName); try { long synchronizerId = Long.parseLong(config.getAsString(DB.PRIMARY_KEY)); DBHelper.deleteAccount(mDB, synchronizerId); @@ -900,14 +900,14 @@ protected Synchronizer.Status doInBackground(String... params0) { synchronizer.downloadWorkout(w, ref.workoutKey); if (w != f) { if (!compareFiles(w, f)) { - Log.e(getClass().getName(), "overwriting " + f.getPath() + " with " + w.getPath()); + Log.w(getClass().getName(), "overwriting " + f.getPath() + " with " + w.getPath()); // TODO dialog //noinspection ResultOfMethodCallIgnored f.delete(); //noinspection ResultOfMethodCallIgnored w.renameTo(f); } else { - Log.e(getClass().getName(), "file identical...deleting temporary " + w.getPath()); + Log.i(getClass().getName(), "file identical...deleting temporary " + w.getPath()); //noinspection ResultOfMethodCallIgnored w.delete(); } diff --git a/app/src/main/org/runnerup/export/oauth2client/OAuth2Activity.java b/app/src/main/org/runnerup/export/oauth2client/OAuth2Activity.java index 8c60ab3d6..14ef4a0a7 100644 --- a/app/src/main/org/runnerup/export/oauth2client/OAuth2Activity.java +++ b/app/src/main/org/runnerup/export/oauth2client/OAuth2Activity.java @@ -172,7 +172,7 @@ public void onPageFinished(WebView view, String url) { } if (e != null) { - Log.e(getClass().getName(), "e: " + e); + Log.d(getClass().getName(), "e: " + e); Intent res = new Intent().putExtra("error", e); OAuth2Activity.this.setResult(AppCompatActivity.RESULT_CANCELED, res); OAuth2Activity.this.finish(); diff --git a/app/src/main/org/runnerup/tracker/Tracker.java b/app/src/main/org/runnerup/tracker/Tracker.java index 4163f54cb..f5cf7d138 100644 --- a/app/src/main/org/runnerup/tracker/Tracker.java +++ b/app/src/main/org/runnerup/tracker/Tracker.java @@ -206,7 +206,7 @@ public void run(TrackerComponent component, TrackerComponent.ResultCode resultCo state.set(TrackerState.INITIALIZED); } - Log.e(getClass().getName(), "state.set(" + getState() + ")"); + Log.d(getClass().getName(), "state.set(" + getState() + ")"); handleNextState(); } }; @@ -251,14 +251,14 @@ private void handleNextState() { } public void connect() { - Log.e(getClass().getName(), "Tracker.connect() - state: " + state.get()); + Log.d(getClass().getName(), "Tracker.connect() - state: " + state.get()); switch (state.get()) { case INIT: setup(); case INITIALIZING: case CLEANUP: nextState = TrackerState.CONNECTED; - Log.e(getClass().getName(), " => nextState: " + nextState); + Log.d(getClass().getName(), " => nextState: " + nextState); return; case INITIALIZED: break; @@ -321,7 +321,7 @@ private long createActivity(int sport) { tmp.put(DB.LOCATION.LAP, 0); // always start with lap 0 mDBWriter = new PersistentGpsLoggerListener(mDB, DB.LOCATION.TABLE, tmp, logGpxAccuracy); } catch (IllegalStateException ex) { - Log.e(getClass().getName(), "Query failed:", ex); + Log.i(getClass().getName(), "Query failed:", ex); } return mActivityId; } diff --git a/app/src/main/org/runnerup/tracker/component/TrackerComponentCollection.java b/app/src/main/org/runnerup/tracker/component/TrackerComponentCollection.java index 8587a02cd..61e1e3f82 100644 --- a/app/src/main/org/runnerup/tracker/component/TrackerComponentCollection.java +++ b/app/src/main/org/runnerup/tracker/component/TrackerComponentCollection.java @@ -211,23 +211,23 @@ private ResultCode forEach( handler.post( () -> { synchronized (components) { - Log.e( + Log.d( getName(), component1.getName() + " " + msg + " => " + resultCode); if (!pending.containsKey(key)) return; TrackerComponent check = pending.remove(key); if (BuildConfig.DEBUG && check != component1) { - Log.e(getName(), component1.getName() + " != " + check.getName()); + Log.w(getName(), component1.getName() + " != " + check.getName()); throw new AssertionError(); } components.put(key, new Pair<>(component1, resultCode)); if (pending.isEmpty()) { - Log.e(getName(), " => runCallback()"); + Log.d(getName(), " => runCallback()"); callback.run(TrackerComponentCollection.this, getResult(components)); } } }), context); - Log.e(getName(), component.getName() + " " + msg + " => " + res); + Log.d(getName(), component.getName() + " " + msg + " => " + res); if (res != ResultCode.RESULT_PENDING) { components.put(key, new Pair<>(component, res)); } else { @@ -237,7 +237,7 @@ private ResultCode forEach( } if (!pending.isEmpty()) return ResultCode.RESULT_PENDING; else { - Log.e(getName(), " => return directly"); + Log.d(getName(), " => return directly"); return getResult(components); } } diff --git a/app/src/main/org/runnerup/tracker/component/TrackerElevation.java b/app/src/main/org/runnerup/tracker/component/TrackerElevation.java index 191231254..51b3e7a5c 100644 --- a/app/src/main/org/runnerup/tracker/component/TrackerElevation.java +++ b/app/src/main/org/runnerup/tracker/component/TrackerElevation.java @@ -65,7 +65,7 @@ GeoidAdjust GetAltitudeAdjust(Context context) { Geoid.init(context.getAssets().open("egm96-delta.dat")); return new GeoidAdjust(); } catch (IOException e) { - Log.e("TrackerElevation", "Altitude correction " + e); + Log.i("TrackerElevation", "Altitude correction " + e); } return null; } diff --git a/app/src/main/org/runnerup/util/Formatter.java b/app/src/main/org/runnerup/util/Formatter.java index 51f715433..a4c78e712 100644 --- a/app/src/main/org/runnerup/util/Formatter.java +++ b/app/src/main/org/runnerup/util/Formatter.java @@ -198,7 +198,7 @@ public static boolean getUseMetric(Resources res, SharedPreferences prefs, Edito private static boolean guessDefaultUnit(Resources res, Editor editor) { String countryCode = Locale.getDefault().getCountry(); - Log.e("Formatter", "guessDefaultUnit: countryCode: " + countryCode); + Log.i("Formatter", "guessDefaultUnit: countryCode: " + countryCode); if (countryCode.equals("")) return true; // km; String key = res.getString(R.string.pref_unit); if ("US".contentEquals(countryCode) || "GB".contentEquals(countryCode)) { diff --git a/app/src/main/org/runnerup/util/GraphWrapper.java b/app/src/main/org/runnerup/util/GraphWrapper.java index c163f6270..429e013c8 100644 --- a/app/src/main/org/runnerup/util/GraphWrapper.java +++ b/app/src/main/org/runnerup/util/GraphWrapper.java @@ -455,7 +455,7 @@ void KolmogorovZurbenko(int n, int len) { public void complete(final GraphView graphView) { avg_velocity /= velocityList.size(); - Log.e(getClass().getName(), "graph: " + velocityList.size() + " points"); + Log.d(getClass().getName(), "graph: " + velocityList.size() + " points"); boolean smoothData = PreferenceManager.getDefaultSharedPreferences(graphView.getContext()) @@ -465,7 +465,7 @@ public void complete(final GraphView graphView) { .getResources() .getString(R.string.pref_pace_graph_smoothing), true); - if (velocityList.size() > 0 && smoothData) { + if (!velocityList.isEmpty() && smoothData) { GraphFilter f = new GraphFilter(velocityList); final String defaultFilterList = graphView.getContext().getResources().getString(R.string.mm31kz513sg5); @@ -478,35 +478,35 @@ public void complete(final GraphView graphView) { .getString(R.string.pref_pace_graph_smoothing_filters), defaultFilterList); final String[] filters = filterList.split(";"); - System.err.print("Applying filters(" + filters.length + ", >" + filterList + "<):"); + StringBuilder s = new StringBuilder("Applying filters(" + filters.length + ", >" + filterList + "<):"); for (String filter : filters) { int[] args = getArgs(filter); if (filter.startsWith("mm")) { if (args.length == 1) { f.movingMedian(args[0]); - System.err.print(" mm(" + args[0] + ")"); + s.append(" mm(").append(args[0]).append(")"); } } else if (filter.startsWith("ma")) { if (args.length == 1) { f.movingAvergage(args[0]); - System.err.print(" ma(" + args[0] + ")"); + s.append(" ma(").append(args[0]).append(")"); } } else if (filter.startsWith("kz")) { if (args.length == 2) { f.KolmogorovZurbenko(args[0], args[1]); - System.err.print(" kz(" + args[0] + "," + args[1] + ")"); + s.append(" kz(").append(args[0]).append(",").append(args[1]).append(")"); } } else if (filter.startsWith("sg")) { if (args.length == 1 && args[0] == 5) { f.SavitzkyGolay5(); - System.err.print(" sg(5)"); + s.append(" sg(5)"); } else if (args.length == 1 && args[0] == 7) { f.SavitzkyGolay7(); - System.err.print(" sg(7)"); + s.append(" sg(7)"); } } } - Log.e(getClass().getName(), ""); + Log.d(getClass().getName(), s.toString()); f.complete(); } LineGraphSeries graphViewData = @@ -547,16 +547,16 @@ public void complete(final GraphView graphView) { }); if (showHRZhist) { - System.err.print("HR Zones:"); + StringBuilder s = new StringBuilder("HR Zones:"); double sum = 0; for (double aHrzHist : hrzHist) { sum += aHrzHist; } for (int i = 0; i < hrzHist.length; i++) { hrzHist[i] = hrzHist[i] / sum; - System.err.print(" " + hrzHist[i]); + s.append(" ").append(hrzHist[i]); } - Log.e(getClass().getName(), "\n"); + Log.d(getClass().getName(), s.toString()); hrzonesBar.pushHrzData(hrzHist); } } @@ -662,8 +662,8 @@ protected GraphProducer doInBackground(LoadParam... params) { graphData.clearSmooth(xAxis.getX(tot_distance, tot_time)); ll.close(); - Log.e(getClass().getName(), "Finished loading " + cnt + " points" - + " => " + graphData.velocityList.size() + " points"); + // Log.e(getClass().getName(), "Finished loading " + cnt + " points" + // + " => " + graphData.velocityList.size() + " points"); return graphData; } diff --git a/app/src/main/org/runnerup/util/HRZones.java b/app/src/main/org/runnerup/util/HRZones.java index ac58ed568..c8d0a686f 100644 --- a/app/src/main/org/runnerup/util/HRZones.java +++ b/app/src/main/org/runnerup/util/HRZones.java @@ -50,11 +50,11 @@ public void reload() { zones = null; } if (zones != null) { - System.err.print("loaded: (" + str + ")"); + StringBuilder s = new StringBuilder("loaded: (" + str + ")"); for (int zone : zones) { - System.err.print(" " + zone); + s.append(" ").append(zone); } - Log.e(getClass().getName(), ""); + Log.d(getClass().getName(), s.toString()); } } @@ -80,7 +80,7 @@ public double getZone(double value) { double lo = (z == 0) ? 0 : zones[z - 1]; double hi = zones[z]; double add = (value - lo) / (hi - lo); - Log.e( + Log.d( getClass().getName(), "value: " + value + ", z: " + z + ", lo: " + lo + ", hi: " + hi + ", add: " + add); return z + add; diff --git a/app/src/main/org/runnerup/view/DetailActivity.java b/app/src/main/org/runnerup/view/DetailActivity.java index 6061e33ab..fc260237a 100644 --- a/app/src/main/org/runnerup/view/DetailActivity.java +++ b/app/src/main/org/runnerup/view/DetailActivity.java @@ -318,7 +318,7 @@ public WindowInsetsCompat onApplyWindowInsets( LinearLayout hrzonesBarLayout = findViewById(R.id.hrzonesBarLayout); boolean use_distance_as_x = !Sport.isWithoutGps(sport.getValueInt()); graphWrapper = new GraphWrapper(this, graphTabLayout, hrzonesBarLayout, - formatter, mDB, mID, use_distance_as_x); + formatter, mDB, mID, use_distance_as_x); if (this.mode == MODE_SAVE) { resumeButton.setOnClickListener(resumeButtonClick); diff --git a/app/src/main/org/runnerup/view/HRZonesActivity.java b/app/src/main/org/runnerup/view/HRZonesActivity.java index 8e18f4cc7..7e7097154 100644 --- a/app/src/main/org/runnerup/view/HRZonesActivity.java +++ b/app/src/main/org/runnerup/view/HRZonesActivity.java @@ -244,7 +244,7 @@ private void load() { EditText hi = zones.get(2 * zone + 1); lo.setText(String.format(Locale.getDefault(), "%d", values.first)); hi.setText(String.format(Locale.getDefault(), "%d", values.second)); - Log.e( + Log.i( getClass().getName(), "loaded " + (zone + 1) + " " + values.first + "-" + values.second); } @@ -291,13 +291,14 @@ private void recomputeZones() { private void saveHR() { try { Vector vals = new Vector<>(); - System.err.print("saving: "); + StringBuilder s = new StringBuilder("saving:"); for (int i = 0; i < zones.size(); i += 2) { vals.add(Integer.valueOf(zones.get(i).getText().toString())); - System.err.print(" " + vals.lastElement()); + s.append(" ").append(vals.lastElement()); } vals.add(Integer.valueOf(zones.lastElement().getText().toString())); - Log.e(getClass().getName(), " " + vals.lastElement()); + s.append(" ").append(vals.lastElement()); + Log.d(getClass().getName(), s.toString()); hrZones.save(vals); } catch (Exception ex) { } diff --git a/app/src/main/org/runnerup/view/HRZonesBar.java b/app/src/main/org/runnerup/view/HRZonesBar.java index e26dce8bd..1d2f404dd 100644 --- a/app/src/main/org/runnerup/view/HRZonesBar.java +++ b/app/src/main/org/runnerup/view/HRZonesBar.java @@ -79,7 +79,7 @@ public void onDraw(Canvas canvas) { float totalWidth = getWidth(); if (totalWidth <= 0 || calculatedBarHeight < 10) { - Log.e(getClass().getName(), "Not enough space to display the heart-rate zone bar"); + Log.i(getClass().getName(), "Not enough space to display the heart-rate zone bar"); activity.findViewById(R.id.hrzonesBarLayout).setVisibility(View.GONE); return; } diff --git a/app/src/main/org/runnerup/view/MainLayout.java b/app/src/main/org/runnerup/view/MainLayout.java index 34c71d692..708dccdc6 100644 --- a/app/src/main/org/runnerup/view/MainLayout.java +++ b/app/src/main/org/runnerup/view/MainLayout.java @@ -112,7 +112,7 @@ public void onCreate(Bundle savedInstanceState) { // clear basicTargetType between application startup/shutdown pref.edit().remove(getString(R.string.pref_basic_target_type)).apply(); - Log.e( + Log.i( getClass().getName(), "app-version: " + versionCode + ", upgradeState: " + upgradeState + ", km: " + km); @@ -295,7 +295,7 @@ private void handleBundled(AssetManager mgr, String srcBase, String dstBase) { // Normal, src is directory for first call } - Log.v(getClass().getName(), "Found: " + src + ", " + dst + ", isFile: " + isFile); + Log.d(getClass().getName(), "Found: " + src + ", " + dst + ", isFile: " + isFile); if (!isFile) { // The request is hierarchical, source is still on a directory level @@ -303,7 +303,7 @@ private void handleBundled(AssetManager mgr, String srcBase, String dstBase) { //noinspection ResultOfMethodCallIgnored dstDir.mkdir(); if (!dstDir.isDirectory()) { - Log.w( + Log.i( getClass().getName(), "Failed to copy " + src + " as \"" + dstBase + "\" is not a directory!"); continue; @@ -313,7 +313,7 @@ private void handleBundled(AssetManager mgr, String srcBase, String dstBase) { // Source is a file, ready to copy File dstFile = new File(dst); if (dstFile.isDirectory() || dstFile.isFile()) { - Log.v( + Log.d( getClass().getName(), "Skip: " + dst @@ -328,13 +328,13 @@ private void handleBundled(AssetManager mgr, String srcBase, String dstBase) { String key = "install_bundled_" + add; SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); if (pref.contains(key)) { - Log.v(getClass().getName(), "Skip already existing pref: " + key); + Log.d(getClass().getName(), "Skip already existing pref: " + key); continue; } pref.edit().putBoolean(key, true).apply(); - Log.v(getClass().getName(), "Copying: " + dst); + Log.d(getClass().getName(), "Copying: " + dst); InputStream input = null; try { input = mgr.open(src); diff --git a/app/src/main/org/runnerup/view/ManualActivity.java b/app/src/main/org/runnerup/view/ManualActivity.java index eb65a4d01..1d7a707bb 100644 --- a/app/src/main/org/runnerup/view/ManualActivity.java +++ b/app/src/main/org/runnerup/view/ManualActivity.java @@ -110,18 +110,18 @@ public void onActivityResult( super.onActivityResult(requestCode, resultCode, data); if (data != null) { if (data.getStringExtra("url") != null) - Log.e( + Log.d( getClass().getName(), "data.getStringExtra(\"url\") => " + data.getStringExtra("url")); if (data.getStringExtra("ex") != null) - Log.e(getClass().getName(), "data.getStringExtra(\"ex\") => " + data.getStringExtra("ex")); + Log.d(getClass().getName(), "data.getStringExtra(\"ex\") => " + data.getStringExtra("ex")); if (data.getStringExtra("obj") != null) - Log.e( + Log.d( getClass().getName(), "data.getStringExtra(\"obj\") => " + data.getStringExtra("obj")); } } void setManualPace(String distance, String duration) { - Log.e(getClass().getName(), "distance: >" + distance + "< duration: >" + duration + "<"); + Log.d(getClass().getName(), "distance: >" + distance + "< duration: >" + duration + "<"); double dist = SafeParse.parseDouble(distance, 0); // convert to meters long seconds = SafeParse.parseSeconds(duration, 0); if (seconds == 0) { diff --git a/app/src/main/org/runnerup/view/RunActivity.java b/app/src/main/org/runnerup/view/RunActivity.java index f6700f654..65cfb579c 100644 --- a/app/src/main/org/runnerup/view/RunActivity.java +++ b/app/src/main/org/runnerup/view/RunActivity.java @@ -198,7 +198,7 @@ public void handleOnBackPressed() { @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); - Log.e(getClass().getName(), "onConfigurationChange => do NOTHING!!"); + Log.d(getClass().getName(), "onConfigurationChange => do NOTHING!!"); } @Override diff --git a/app/src/main/org/runnerup/view/StartFragment.java b/app/src/main/org/runnerup/view/StartFragment.java index b7c24cb93..cea3702ac 100644 --- a/app/src/main/org/runnerup/view/StartFragment.java +++ b/app/src/main/org/runnerup/view/StartFragment.java @@ -462,7 +462,7 @@ public void onPause() { if (mTracker != null && ((mTracker.getState() == TrackerState.INITIALIZED) || (mTracker.getState() == TrackerState.INITIALIZING))) { - Log.e(getClass().getName(), "mTracker.reset()"); + Log.i(getClass().getName(), "mTracker.reset()"); mTracker.reset(); } } @@ -533,7 +533,7 @@ private void onGpsTrackerBound() { if (!missingEssentialPermission && getAutoStartGps()) { startGps(); } else { - Log.e(getClass().getName(), "onGpsTrackerBound state: " + mTracker.getState()); + Log.d(getClass().getName(), "onGpsTrackerBound state: " + mTracker.getState()); switch (mTracker.getState()) { case INIT: case CLEANUP: @@ -561,7 +561,7 @@ public boolean getAutoStartGps() { } private void startGps() { - Log.v(getClass().getName(), "StartFragment.startGps()"); + Log.d(getClass().getName(), "StartFragment.startGps()"); if (!sportWithoutGps) { if (!mGpsStatus.isEnabled()) { startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)); @@ -580,7 +580,7 @@ private void startGps() { } public void stopGps() { - Log.e(getClass().getName(), "StartFragment.stopGps() skipStop: " + this.runActivityPending); + Log.d(getClass().getName(), "StartFragment.stopGps() skipStop: " + this.runActivityPending); if (runActivityPending) { return; } @@ -1280,12 +1280,12 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { if (data != null) { if (data.getStringExtra("url") != null) - Log.e( + Log.d( getClass().getName(), "data.getStringExtra(\"url\") => " + data.getStringExtra("url")); if (data.getStringExtra("ex") != null) - Log.e(getClass().getName(), "data.getStringExtra(\"ex\") => " + data.getStringExtra("ex")); + Log.d(getClass().getName(), "data.getStringExtra(\"ex\") => " + data.getStringExtra("ex")); if (data.getStringExtra("obj") != null) - Log.e( + Log.d( getClass().getName(), "data.getStringExtra(\"obj\") => " + data.getStringExtra("obj")); } if (requestCode == START_ACTIVITY) { diff --git a/app/src/main/org/runnerup/workout/EndOfLapSuppression.java b/app/src/main/org/runnerup/workout/EndOfLapSuppression.java index 5634a56c0..7ce88f85b 100644 --- a/app/src/main/org/runnerup/workout/EndOfLapSuppression.java +++ b/app/src/main/org/runnerup/workout/EndOfLapSuppression.java @@ -100,7 +100,7 @@ private boolean suppressInterval(Trigger trigger, Workout w) { double distance = w.getDistance(Scope.LAP); if ((distance - lapDuration) == lapDistanceLimit) { - Log.e( + Log.i( getClass().getName(), "suppressing trigger! distance: " + distance + ", lapDistance: " + lapDuration); return true; diff --git a/app/src/main/org/runnerup/workout/TargetTrigger.java b/app/src/main/org/runnerup/workout/TargetTrigger.java index eec8899e5..fae5b0518 100644 --- a/app/src/main/org/runnerup/workout/TargetTrigger.java +++ b/app/src/main/org/runnerup/workout/TargetTrigger.java @@ -111,16 +111,15 @@ public boolean onTick(Workout w) { for (int i = 0; i < elapsed_seconds; i++) { addObservation(val_now); } - // Log.e(getName(), "val_now: " + val_now + " elapsed: " + - // elapsed_seconds); + // Log.d(getName(), "val_now: " + val_now + " elapsed: " + elapsed_seconds); if (graceCount > 0) { // only emit coaching ever so often - // Log.e(getName(), "graceCount: " + graceCount); + // Log.d(getName(), "graceCount: " + graceCount); graceCount -= elapsed_seconds; } else { double avg = getValue(); double cmp = range.compare(avg); - // Log.e(getName(), " => avg: " + avg + " => cmp: " + cmp); + // Log.d(getName(), " => avg: " + avg + " => cmp: " + cmp); if (cmp == 0) { graceCount = minGraceCount; return false; diff --git a/app/src/main/org/runnerup/workout/Trigger.java b/app/src/main/org/runnerup/workout/Trigger.java index 1c28fbce4..ea36450a2 100644 --- a/app/src/main/org/runnerup/workout/Trigger.java +++ b/app/src/main/org/runnerup/workout/Trigger.java @@ -50,7 +50,7 @@ public void onEnd(Workout s) { void fire(Workout w) { for (TriggerSuppression s : triggerSuppression) { if (s.suppress(this, w)) { - Log.e(getClass().getName(), "trigger: " + this + "suppressed by: " + s); + Log.v(getClass().getName(), "trigger: " + this + "suppressed by: " + s); return; } } diff --git a/app/src/main/org/runnerup/workout/WorkoutBuilder.java b/app/src/main/org/runnerup/workout/WorkoutBuilder.java index 3eec43d3f..502bdb941 100644 --- a/app/src/main/org/runnerup/workout/WorkoutBuilder.java +++ b/app/src/main/org/runnerup/workout/WorkoutBuilder.java @@ -409,7 +409,7 @@ private static Trigger hasEndOfLapTrigger(List triggers) { private static void checkDuplicateTriggers(Step step) { if (hasEndOfLapTrigger(step.triggers) != null) { - Log.e("WorkoutBuilder", "hasEndOfLapTrigger()"); + Log.d("WorkoutBuilder", "hasEndOfLapTrigger()"); /* * The end of lap trigger can be a duplicate of a distance based interval trigger * 1) in a step with distance duration, that is a multiple of the interval-distance diff --git a/app/src/main/org/runnerup/workout/WorkoutSerializer.java b/app/src/main/org/runnerup/workout/WorkoutSerializer.java index 72d91fdc4..b57f2d54c 100644 --- a/app/src/main/org/runnerup/workout/WorkoutSerializer.java +++ b/app/src/main/org/runnerup/workout/WorkoutSerializer.java @@ -439,7 +439,7 @@ public static Workout readFile(Context ctx, String name) throws FileNotFoundException, JSONException { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); File fin = getFile(ctx, name); - Log.e("WorkoutSerializer", "reading " + fin.getPath()); + Log.d("WorkoutSerializer", "reading " + fin.getPath()); Workout w = readJSON(new FileReader(fin)); w.sport = @@ -452,7 +452,7 @@ public static Workout readFile(Context ctx, String name) public static void writeFile(Context ctx, String name, Workout workout) throws IOException, JSONException { File fout = getFile(ctx, name); - Log.e("WorkoutSerializer", "writing " + fout.getPath()); + Log.v("WorkoutSerializer", "writing " + fout.getPath()); writeJSON(new FileWriter(fout), workout); } diff --git a/app/src/main/org/runnerup/workout/feedback/RUTextToSpeech.java b/app/src/main/org/runnerup/workout/feedback/RUTextToSpeech.java index c40e6cba5..bc2701856 100644 --- a/app/src/main/org/runnerup/workout/feedback/RUTextToSpeech.java +++ b/app/src/main/org/runnerup/workout/feedback/RUTextToSpeech.java @@ -70,11 +70,11 @@ public RUTextToSpeech(TextToSpeech tts, boolean mute_, Context context) { case TextToSpeech.LANG_COUNTRY_AVAILABLE: case TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE: res = tts.setLanguage(locale); - Log.e(getClass().getName(), "setLanguage(" + locale.getDisplayLanguage() + ") => " + res); + Log.d(getClass().getName(), "setLanguage(" + locale.getDisplayLanguage() + ") => " + res); break; case TextToSpeech.LANG_MISSING_DATA: case TextToSpeech.LANG_NOT_SUPPORTED: - Log.e( + Log.v( getClass().getName(), "setLanguage(" + locale.getDisplayLanguage() + ") => MISSING: " + res); break; @@ -109,14 +109,14 @@ int speak(String text, UtterancePrio prio, boolean flush, HashMap { if (dataItem != null) { wearNode = dataItem.getUri().getHost(); - Log.e(getName(), "getDataItem => wearNode:" + wearNode); + Log.d(getName(), "getDataItem => wearNode:" + wearNode); } }); } @@ -231,12 +231,12 @@ public void onBind(HashMap bindValues) { case WORKOUT_TYPE.INTERVAL: case WORKOUT_TYPE.ADVANCED: initIntervalScreens(); - Log.e("TrackerWear::onBind()", "initIntervalScreens()"); + Log.d("TrackerWear::onBind()", "initIntervalScreens()"); break; default: case WORKOUT_TYPE.BASIC: initBasicScreens(); - Log.e("TrackerWear::onBind()", "initBasicScreens()"); + Log.d("TrackerWear::onBind()", "initBasicScreens()"); break; } } @@ -249,7 +249,7 @@ public void onStart() { } private void setTrackerState(TrackerState val) { - Log.e(getName(), "setTrackerState(" + val + ")"); + Log.d(getName(), "setTrackerState(" + val + ")"); Bundle b = new Bundle(); b.putInt(Wear.TrackerState.STATE, val.getValue()); setData(Wear.Path.TRACKER_STATE, b); @@ -433,7 +433,7 @@ public boolean isConnected() { @Override public void onMessageReceived(final MessageEvent messageEvent) { - Log.e(getName(), "onMessageReceived: " + messageEvent); + Log.d(getName(), "onMessageReceived: " + messageEvent); // note: skip state checking, do that in receiver instead if (Wear.Path.MSG_CMD_WORKOUT_PAUSE.contentEquals(messageEvent.getPath())) { sendLocalBroadcast(Intents.PAUSE_WORKOUT); @@ -497,7 +497,7 @@ private void clearData(boolean self) { @Override public void onDataChanged(final DataEventBuffer dataEvents) { for (DataEvent ev : dataEvents) { - Log.e(getName(), "onDataChanged: " + ev.getDataItem().getUri()); + Log.d(getName(), "onDataChanged: " + ev.getDataItem().getUri()); String path = ev.getDataItem().getUri().getPath(); if (Constants.Wear.Path.WEAR_NODE_ID.contentEquals(path)) { setWearNode(ev); diff --git a/hrdevice/src/org/runnerup/hr/Bt20Base.java b/hrdevice/src/org/runnerup/hr/Bt20Base.java index 49c937512..e74fbb717 100644 --- a/hrdevice/src/org/runnerup/hr/Bt20Base.java +++ b/hrdevice/src/org/runnerup/hr/Bt20Base.java @@ -28,6 +28,8 @@ import android.os.Build; import android.os.Handler; import android.os.SystemClock; +import android.util.Log; + import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import java.io.IOException; @@ -64,7 +66,7 @@ public static boolean startEnableIntentImpl(AppCompatActivity activity, int requ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { - System.err.println("No BLUETOOTH_CONNECT permission in startEnableIntentImpl"); + Log.d(Bt20Base.class.getName(), "No BLUETOOTH_CONNECT permission in startEnableIntentImpl"); return false; } activity.startActivityForResult( diff --git a/hrdevice/src/org/runnerup/hr/BtHRBase.java b/hrdevice/src/org/runnerup/hr/BtHRBase.java index ef8ea600c..19fe5b52a 100644 --- a/hrdevice/src/org/runnerup/hr/BtHRBase.java +++ b/hrdevice/src/org/runnerup/hr/BtHRBase.java @@ -18,6 +18,8 @@ import android.os.Handler; import android.os.Looper; +import android.util.Log; + import java.util.UUID; abstract class BtHRBase implements HRProvider { @@ -44,6 +46,6 @@ void log(final String msg) { if (hrClient != null) hrClient.log(BtHRBase.this, msg); }); } - } else System.err.println(msg); + } else Log.d(getClass().getName(), msg); } } diff --git a/hrdevice/src/org/runnerup/hr/HRManager.java b/hrdevice/src/org/runnerup/hr/HRManager.java index 57d0633a5..97836f638 100644 --- a/hrdevice/src/org/runnerup/hr/HRManager.java +++ b/hrdevice/src/org/runnerup/hr/HRManager.java @@ -83,7 +83,7 @@ public static HRProvider getHRProvider(Context ctx, String src) { } private static HRProvider getHRProviderImpl(Context ctx, String src) { - System.err.println("getHRProvider(" + src + ")"); + Log.d(HRManager.class.getName(), "getHRProvider(" + src + ")"); if (src.contentEquals(AndroidBLEHRProvider.NAME)) { if (!AndroidBLEHRProvider.checkLibrary(ctx)) return null; return new AndroidBLEHRProvider(ctx); diff --git a/hrdevice/src/org/runnerup/hr/RetryingHRProviderProxy.java b/hrdevice/src/org/runnerup/hr/RetryingHRProviderProxy.java index 93a4a9ea4..a876bad6b 100644 --- a/hrdevice/src/org/runnerup/hr/RetryingHRProviderProxy.java +++ b/hrdevice/src/org/runnerup/hr/RetryingHRProviderProxy.java @@ -2,6 +2,8 @@ import android.os.Handler; import android.os.Looper; +import android.util.Log; + import androidx.appcompat.app.AppCompatActivity; /** @@ -326,7 +328,7 @@ private void log(final String msg) { + requestedState + ", " + msg; - System.err.println(res); + Log.d(getClass().getName(), res); if (client != null) { if (Looper.myLooper() == Looper.getMainLooper()) { client.log(this, msg); diff --git a/wear/src/main/java/org/runnerup/service/ListenerService.java b/wear/src/main/java/org/runnerup/service/ListenerService.java index c9afe46a3..e83ebcb19 100644 --- a/wear/src/main/java/org/runnerup/service/ListenerService.java +++ b/wear/src/main/java/org/runnerup/service/ListenerService.java @@ -24,6 +24,8 @@ import android.content.Context; import android.content.Intent; import android.os.Build; +import android.util.Log; + import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import androidx.wear.ongoing.OngoingActivity; @@ -54,7 +56,7 @@ public class ListenerService extends WearableListenerService { @Override public void onCreate() { super.onCreate(); - System.err.println("ListenerService.onCreate()"); + Log.d(getClass().getName(), "ListenerService.onCreate()"); mGoogleApiClient = new WearableClient(getApplicationContext()); mGoogleApiClient.readData(Constants.Wear.Path.WEAR_APP, dataItem -> { mainActivityRunning = (dataItem != null); @@ -81,7 +83,7 @@ public void onCreate() { @Override public void onDestroy() { super.onDestroy(); - System.err.println("ListenerService.onDestroy()"); + Log.d(getClass().getName(), "ListenerService.onDestroy()"); if (mGoogleApiClient != null) { mGoogleApiClient = null; } @@ -89,14 +91,14 @@ public void onDestroy() { @Override public int onStartCommand(Intent intent, int flags, int startId) { - System.err.println("ListenerService.onStart()"); + Log.d(getClass().getName(), "ListenerService.onStart()"); return super.onStartCommand(intent, flags, startId); } @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent ev : dataEvents) { - System.err.println("onDataChanged: " + ev.getDataItem().getUri()); + Log.d(getClass().getName(), "onDataChanged: " + ev.getDataItem().getUri()); var type = ev.getType(); String path = ev.getDataItem().getUri().getPath(); if (!(type == DataEvent.TYPE_DELETED || type == DataEvent.TYPE_CHANGED)) { @@ -129,19 +131,19 @@ public void onDataChanged(DataEventBuffer dataEvents) { @Override public void onPeerConnected(Node peer) { if (BuildConfig.DEBUG) { - System.err.println("ListenerService.onPeerConnected: " + peer.getId()); + Log.d(getClass().getName(), "ListenerService.onPeerConnected: " + peer.getId()); } } @Override public void onPeerDisconnected(Node peer) { if (BuildConfig.DEBUG) { - System.err.println("ListenerService.onPeerDisconnected: " + peer.getId()); + Log.d(getClass().getName(), "ListenerService.onPeerDisconnected: " + peer.getId()); } } private void maybeShowNotification() { - System.err.println("mainActivityRunning=" + mainActivityRunning + + Log.d(getClass().getName(), "mainActivityRunning=" + mainActivityRunning + ", phoneApp=" + phoneApp + " ,phoneRunning=" + phoneRunning + " ,trackerState=" + trackerState); @@ -160,7 +162,7 @@ private void maybeShowNotification() { } if (mainActivityRunning == null || phoneRunning == null || trackerState == null) { - System.err.println("wait for read"); + Log.d(getClass().getName(), "wait for read"); return; } showNotification(); diff --git a/wear/src/main/java/org/runnerup/service/StateService.java b/wear/src/main/java/org/runnerup/service/StateService.java index d8fba28ad..ee54d52e0 100644 --- a/wear/src/main/java/org/runnerup/service/StateService.java +++ b/wear/src/main/java/org/runnerup/service/StateService.java @@ -21,6 +21,8 @@ import android.content.Intent; import android.os.Bundle; import android.os.IBinder; +import android.util.Log; + import androidx.annotation.NonNull; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; @@ -89,7 +91,7 @@ public void onConnectionFailed(@NonNull ConnectionResult result) {} mGoogleApiClient.connect(); this.headers.registerChangeListener(this); - System.err.println("StateService.onCreate()"); + Log.d(getClass().getName(), "StateService.onCreate()"); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") @@ -101,7 +103,7 @@ private void readData() { mDataClient.readData(Constants.Wear.Path.PHONE_NODE_ID, dataItem -> { if (dataItem != null ) { phoneNode = dataItem.getUri().getHost(); - System.err.println("getDataItem => phoneNode:" + phoneNode); + Log.d(getClass().getName(), "getDataItem => phoneNode:" + phoneNode); } }); mDataClient.readData(Constants.Wear.Path.TRACKER_STATE, dataItem -> { @@ -133,7 +135,7 @@ private void clearData() { @Override public void onDestroy() { - System.err.println("StateService.onDestroy()"); + Log.d(getClass().getName(), "StateService.onDestroy()"); trackerState.clearListeners(); if (mGoogleApiClient != null) { if (mGoogleApiClient.isConnected()) { @@ -191,14 +193,14 @@ public void onMessageReceived(MessageEvent messageEvent) { data = DataMap.fromByteArray(messageEvent.getData()).toBundle(); data.putLong(UPDATE_TIME, System.currentTimeMillis()); } else { - System.err.println("onMessageReceived: " + messageEvent); + Log.d(getClass().getName(), "onMessageReceived: " + messageEvent); } } @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent ev : dataEvents) { - System.err.println("onDataChanged: " + ev.getDataItem().getUri()); + Log.d(getClass().getName(), "onDataChanged: " + ev.getDataItem().getUri()); String path = ev.getDataItem().getUri().getPath(); if (Constants.Wear.Path.PHONE_NODE_ID.contentEquals(path)) { setPhoneNode(ev); @@ -223,7 +225,7 @@ private void setHeaders(DataEvent ev) { if (ev.getType() == DataEvent.TYPE_CHANGED) { Bundle b = DataMapItem.fromDataItem(ev.getDataItem()).getDataMap().toBundle(); b.putLong(UPDATE_TIME, System.currentTimeMillis()); - System.err.println("setHeaders(): b=" + b); + Log.d(getClass().getName(), "setHeaders(): b=" + b); headers.set(b); } else { headers.set(null); diff --git a/wear/src/main/java/org/runnerup/view/MainActivity.java b/wear/src/main/java/org/runnerup/view/MainActivity.java index 65ee0a678..942777608 100644 --- a/wear/src/main/java/org/runnerup/view/MainActivity.java +++ b/wear/src/main/java/org/runnerup/view/MainActivity.java @@ -33,6 +33,7 @@ import android.support.wearable.view.DotsPageIndicator; import android.support.wearable.view.FragmentGridPagerAdapter; import android.support.wearable.view.GridViewPager; +import android.util.Log; import android.widget.LinearLayout; import com.google.android.gms.wearable.DataClient; import com.google.android.gms.wearable.PutDataRequest; @@ -221,12 +222,12 @@ private void update(TrackerState newValue) { private int getRowsForScreen(int col) { Bundle b = headers.get(); if (b == null) { - System.err.println("getRowsForScreen(): headers == null"); + Log.d(getClass().getName(), "getRowsForScreen(): headers == null"); return 1; } ArrayList screens = b.getIntegerArrayList(Wear.RunInfo.SCREENS); if (screens == null) { - System.err.println("getRowsForScreen(): screens == null"); + Log.d(getClass().getName(), "getRowsForScreen(): screens == null"); return 1; } if (col > screens.size()) return 1; @@ -236,12 +237,12 @@ private int getRowsForScreen(int col) { private int getScreensCount() { Bundle b = headers.get(); if (b == null) { - System.err.println("getScreensCount(): headers == null"); + Log.d(getClass().getName(), "getScreensCount(): headers == null"); return 1; } ArrayList screens = b.getIntegerArrayList(Wear.RunInfo.SCREENS); if (screens == null) { - System.err.println("getScreensCount(): screens == null"); + Log.d(getClass().getName(), "getScreensCount(): screens == null"); return 1; } return screens.size(); From a1e639f54b8f534cc415d3506ee2773e1d645c1e Mon Sep 17 00:00:00 2001 From: Gerhard Olsson Date: Mon, 22 Sep 2025 23:44:43 +0200 Subject: [PATCH 2/6] fix: common test compile --- .../org/runnerup/common/util/ValueModelTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/common/src/test/java/org/runnerup/common/util/ValueModelTest.java b/common/src/test/java/org/runnerup/common/util/ValueModelTest.java index 361fde67d..6006a3d3c 100644 --- a/common/src/test/java/org/runnerup/common/util/ValueModelTest.java +++ b/common/src/test/java/org/runnerup/common/util/ValueModelTest.java @@ -4,8 +4,8 @@ import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -71,7 +71,7 @@ public void shouldNotCallListenerIfValueIsNull() { sut.set(null); - verify(listener, never()).onValueChanged(eq(sut), anyObject(), anyObject()); + verify(listener, never()).onValueChanged(eq(sut), any(), any()); } @Test @@ -82,7 +82,7 @@ public void shouldNotCallListenerIfListenerIsRemoved() { sut.unregisterChangeListener(listener); sut.set(newValue); - verify(listener, never()).onValueChanged(eq(sut), anyObject(), anyObject()); + verify(listener, never()).onValueChanged(eq(sut), any(), any()); } @Test @@ -112,9 +112,9 @@ public void shouldNotCallListenersIfClearIsCalled() { sut.set(newValue); - verify(listener1, never()).onValueChanged(eq(sut), anyObject(), anyObject()); - verify(listener2, never()).onValueChanged(eq(sut), anyObject(), anyObject()); - verify(listener3, never()).onValueChanged(eq(sut), anyObject(), anyObject()); + verify(listener1, never()).onValueChanged(eq(sut), any(), any()); + verify(listener2, never()).onValueChanged(eq(sut), any(), any()); + verify(listener3, never()).onValueChanged(eq(sut), any(), any()); } @Test From dcff77821aabcf951c6793f14bd6dab93e88465b Mon Sep 17 00:00:00 2001 From: Gerhard Olsson Date: Sat, 11 Oct 2025 22:59:10 +0200 Subject: [PATCH 3/6] fix: agp 8.13.2 buildtools 36.1.0 Update a few dependencies Fix variable assignment in build.gradle lint Baseline update --- app/build.gradle | 60 +-- app/lint-baseline.xml | 17 +- build.gradle | 6 +- common/build.gradle | 38 +- common/lint-baseline.xml | 13 +- .../org/runnerup/wear/WearableClient.java | 43 +- hrdevice/build.gradle | 30 +- hrdevice/lint-baseline.xml | 388 +----------------- wear/build.gradle | 50 +-- wear/lint-baseline.xml | 2 +- .../org/runnerup/service/ListenerService.java | 12 +- 11 files changed, 159 insertions(+), 500 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 57999fc0e..316bc6695 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,11 +6,11 @@ def getGitHash = providers.exec { android { buildToolsVersion = rootProject.ext.buildToolsVersion - namespace 'org.runnerup' + namespace = 'org.runnerup' compileOptions { - sourceCompatibility JavaVersion.toVersion("17") - targetCompatibility JavaVersion.toVersion("17") + sourceCompatibility = JavaVersion.toVersion("17") + targetCompatibility = JavaVersion.toVersion("17") } sourceSets { @@ -44,13 +44,13 @@ android { flavorDimensions = [ "all" ] productFlavors { latest { - dimension "all" + dimension = "all" // multidexing support, min play support - minSdk rootProject.ext.minSdk - compileSdk rootProject.ext.compileSdk - targetSdk rootProject.ext.targetSdk - versionName rootProject.ext.versionName - versionCode rootProject.ext.latestBaseVersionCode + rootProject.ext.versionCode + minSdk = rootProject.ext.minSdk + compileSdk = rootProject.ext.compileSdk + targetSdk = rootProject.ext.targetSdk + versionName = rootProject.ext.versionName + versionCode = rootProject.ext.latestBaseVersionCode + rootProject.ext.versionCode } } @@ -60,7 +60,7 @@ android { // enable rootProject.ext.allowNonFree && gradle.startParameter.taskNames.contains("assembleLatestRelease") // relevant archs only - these are the only available anyway for newer NDK include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' - universalApk true + universalApk = true } } @@ -86,22 +86,22 @@ android { versionNameSuffix = "-${getGitHash}" } release { - debuggable false - applicationIdSuffix "" + debuggable = false + applicationIdSuffix = "" - minifyEnabled rootProject.ext.allowNonFree - shrinkResources rootProject.ext.allowNonFree + minifyEnabled = rootProject.ext.allowNonFree + shrinkResources = rootProject.ext.allowNonFree proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard.txt' - signingConfig signingConfigs.release + signingConfig = signingConfigs.release } } lint { - baseline file('lint-baseline.xml') - checkReleaseBuilds true - lintConfig file('lint.xml') - showAll true - //textOutput 'stdout' - textReport true + baseline = file('lint-baseline.xml') + checkReleaseBuilds = true + lintConfig = file('lint.xml') + showAll = true + //textOutput = 'stdout' + textReport = true } bundle { language { @@ -110,21 +110,21 @@ android { } } buildFeatures { - aidl true - buildConfig true + aidl = true + buildConfig = true } androidResources { - generateLocaleConfig true + generateLocaleConfig = true } } repositories { google() mavenCentral() //MapBox GraphView - maven { url "https://oss.sonatype.org/content/groups/public/" } //pebblekit + maven { url = "https://oss.sonatype.org/content/groups/public/" } //pebblekit if (rootProject.ext.useMapBox) { maven { - url 'https://api.mapbox.com/downloads/v2/releases/maven' + url = 'https://api.mapbox.com/downloads/v2/releases/maven' authentication { basic(BasicAuthentication) } @@ -144,10 +144,10 @@ repositories { // Duplicate class kotlin.collections.jdk8 (from MapBox?) dependencies { constraints { - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.0") { because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib") } - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.0") { because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib") } } @@ -163,7 +163,7 @@ dependencies { implementation "androidx.viewpager2:viewpager2:1.1.0" implementation "androidx.constraintlayout:constraintlayout:2.2.1" - latestImplementation "com.google.android.material:material:1.12.0" + latestImplementation "com.google.android.material:material:1.13.0" if (rootProject.ext.enableWear) { // Build Wear separately, do not include in phone apk // latestWearApp project(':wear') @@ -172,7 +172,7 @@ dependencies { latestImplementation "com.google.android.gms:play-services-wearable:${rootProject.ext.googlePlayServicesWearableVersion}" } - implementation "com.squareup.okhttp3:okhttp:5.1.0" + implementation "com.squareup.okhttp3:okhttp:5.3.2" latestImplementation 'com.getpebble:pebblekit:4.0.1' if (rootProject.ext.allowNonFree) { // MapBox uses telemetry, without Play there may be exceptions from mapbox (OK to ignore) diff --git a/app/lint-baseline.xml b/app/lint-baseline.xml index ce9768f92..5cb214c6d 100644 --- a/app/lint-baseline.xml +++ b/app/lint-baseline.xml @@ -1,5 +1,16 @@ - + + + + + + file="$GRADLE_USER_HOME/caches/8.13/transforms/42de1f8347fab8a0bff82f7b8295106e/transformed/jetified-mapbox-android-sdk-gl-core-5.2.2/jni/arm64-v8a/libmapbox-gl.so"/> + file="$GRADLE_USER_HOME/caches/8.13/transforms/42de1f8347fab8a0bff82f7b8295106e/transformed/jetified-mapbox-android-sdk-gl-core-5.2.2/jni/arm64-v8a/libmapbox-gl.so"/> - + + + + + consumer) { - mDataClient.getDataItems(new Uri.Builder() - .scheme(WEAR_URI_SCHEME) - .path(path) - .build()) - .addOnCompleteListener(new OnCompleteListener() { - @Override - public void onComplete(Task task) { - if (task.isSuccessful()) { - DataItemBuffer dataItems = task.getResult(); - if (dataItems.getCount() == 0) { - consumer.accept(null); - } else { - for (DataItem dataItem : dataItems) { - consumer.accept(dataItem); + mDataClient + .getDataItems(new Uri.Builder().scheme(WEAR_URI_SCHEME).path(path).build()) + .addOnCompleteListener( + new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + DataItemBuffer dataItems = task.getResult(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (dataItems.getCount() == 0) { + consumer.accept(null); + } else { + for (DataItem dataItem : dataItems) { + consumer.accept(dataItem); + } + } } + dataItems.release(); + } else { + System.out.println("task.getException(): " + task.getException()); } - dataItems.release(); - } else { - System.out.println("task.getException(): " + task.getException()); } - } - }); + }); } public Task putData(String path) { diff --git a/hrdevice/build.gradle b/hrdevice/build.gradle index a51e58d3b..73a0c5749 100644 --- a/hrdevice/build.gradle +++ b/hrdevice/build.gradle @@ -4,13 +4,13 @@ group = "org.runnerup.hr" version = "1.0" android { - namespace 'org.runnerup.hr' - compileSdk rootProject.ext.compileSdk - buildToolsVersion rootProject.ext.buildToolsVersion + namespace = 'org.runnerup.hr' + compileSdk = rootProject.ext.compileSdk + buildToolsVersion = rootProject.ext.buildToolsVersion compileOptions { - sourceCompatibility JavaVersion.toVersion("17") - targetCompatibility JavaVersion.toVersion("17") + sourceCompatibility = JavaVersion.toVersion("17") + targetCompatibility = JavaVersion.toVersion("17") } sourceSets { @@ -25,16 +25,16 @@ android { } } lint { - baseline file('lint-baseline.xml') - checkReleaseBuilds true - //lintConfig file('lint.xml') - showAll true - //textOutput 'stdout' - textReport true + baseline = file('lint-baseline.xml') + checkReleaseBuilds = true + //lintConfig = file('lint.xml') + showAll = true + //textOutput = 'stdout' + textReport = true } defaultConfig { - minSdk rootProject.ext.minSdk - targetSdk rootProject.ext.targetSdk + minSdk = rootProject.ext.minSdk + targetSdk = rootProject.ext.targetSdk if (rootProject.ext.antPlusLibName) { buildConfigField 'Boolean', 'ANTPLUS_ENABLED', "true" @@ -44,8 +44,8 @@ android { } } buildFeatures { - aidl true - buildConfig true + aidl = true + buildConfig = true } } diff --git a/hrdevice/lint-baseline.xml b/hrdevice/lint-baseline.xml index 73f790af7..375963cc0 100644 --- a/hrdevice/lint-baseline.xml +++ b/hrdevice/lint-baseline.xml @@ -1,389 +1,15 @@ - + + id="UnusedAttribute" + message="Attribute `usesPermissionFlags` is only used in API level 31 and higher (current min is 21)" + errorLine1=" android:usesPermissionFlags="neverForLocation" android:minSdkVersion="31"/>" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/wear/build.gradle b/wear/build.gradle index ce1dc77da..e6fcced94 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -1,21 +1,21 @@ apply plugin: 'com.android.application' android { - namespace 'org.runnerup' - compileSdk rootProject.ext.compileSdk + namespace = 'org.runnerup' + compileSdk = rootProject.ext.compileSdk buildToolsVersion = rootProject.ext.buildToolsVersion compileOptions { - sourceCompatibility JavaVersion.toVersion("17") - targetCompatibility JavaVersion.toVersion("17") + sourceCompatibility = JavaVersion.toVersion("17") + targetCompatibility = JavaVersion.toVersion("17") } defaultConfig { - minSdk 25 - targetSdk rootProject.ext.targetSdk - versionName rootProject.ext.versionName - versionCode rootProject.ext.latestBaseVersionCode + rootProject.ext.versionCode + 1 - applicationId rootProject.ext.applicationId + minSdk = 25 + targetSdk = rootProject.ext.targetSdk + versionName = rootProject.ext.versionName + versionCode = rootProject.ext.latestBaseVersionCode + rootProject.ext.versionCode + 1 + applicationId = rootProject.ext.applicationId } signingConfigs { @@ -26,27 +26,27 @@ android { buildTypes { release { - debuggable false - minifyEnabled true - shrinkResources true + debuggable = false + minifyEnabled = true + shrinkResources = true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.txt' - signingConfig signingConfigs.release + signingConfig = signingConfigs.release } debug { - applicationIdSuffix ".debug" + applicationIdSuffix = ".debug" } } lint { - baseline file('lint-baseline.xml') - checkReleaseBuilds true - lintConfig file('lint.xml') - showAll true - //textOutput 'stdout' - textReport true + baseline = file('lint-baseline.xml') + checkReleaseBuilds = true + lintConfig = file('lint.xml') + showAll = true + //textOutput = 'stdout' + textReport = true } - namespace 'org.runnerup' + namespace = 'org.runnerup' buildFeatures { - buildConfig true + buildConfig = true } } @@ -58,10 +58,10 @@ repositories { // Duplicate class kotlin.collections.jdk8 (from MapBox?) dependencies { constraints { - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.0") { because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib") } - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.0") { because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib") } } @@ -76,7 +76,7 @@ dependencies { implementation "com.google.android.gms:play-services-wearable:${rootProject.ext.googlePlayServicesWearableVersion}" implementation "androidx.wear:wear:1.3.0" - implementation "androidx.wear:wear-ongoing:1.0.0" + implementation "androidx.wear:wear-ongoing:1.1.0" // Includes LocusIdCompat and new Notification categories for Ongoing Activity. implementation "androidx.core:core:1.16.0" } diff --git a/wear/lint-baseline.xml b/wear/lint-baseline.xml index 0e17fd917..1d8692c05 100644 --- a/wear/lint-baseline.xml +++ b/wear/lint-baseline.xml @@ -1,4 +1,4 @@ - + diff --git a/wear/src/main/java/org/runnerup/service/ListenerService.java b/wear/src/main/java/org/runnerup/service/ListenerService.java index e83ebcb19..0a0bfb20f 100644 --- a/wear/src/main/java/org/runnerup/service/ListenerService.java +++ b/wear/src/main/java/org/runnerup/service/ListenerService.java @@ -264,9 +264,15 @@ private void updateNotification() { if (ongoingActivity == null) { return; } - ongoingActivity.update(this, new Status.Builder() - .addPart("Status", - new TextPart(getStatusString())).build()); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && checkSelfPermission(android.Manifest.permission.POST_NOTIFICATIONS) + != android.content.pm.PackageManager.PERMISSION_GRANTED) { + return; + } + + ongoingActivity.update( + this, new Status.Builder().addPart("Status", new TextPart(getStatusString())).build()); } private void dismissNotification() { From f1fa1eada83a60a200b4967a60c6928ab6415a0d Mon Sep 17 00:00:00 2001 From: Gerhard Olsson Date: Tue, 16 Dec 2025 21:35:30 +0100 Subject: [PATCH 4/6] feat: Android 16 / SDK 36.1 (#1298) --- build.gradle | 4 ++-- wear/build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index ec15b3162..7ce75434f 100644 --- a/build.gradle +++ b/build.gradle @@ -16,8 +16,8 @@ project.ext { //Common settings for most builds //Note that Android Studio does not know about the 'ext' module and will warn buildToolsVersion = '36.1.0' //Update Travis manually - compileSdk = 35 //Update Travis manually - targetSdk = 35 + compileSdk = 36.1 //Update Travis manually + targetSdk = 36.1 minSdk = 21 appcompat_version = "1.7.1" diff --git a/wear/build.gradle b/wear/build.gradle index e6fcced94..5ecc61229 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -78,7 +78,7 @@ dependencies { implementation "androidx.wear:wear:1.3.0" implementation "androidx.wear:wear-ongoing:1.1.0" // Includes LocusIdCompat and new Notification categories for Ongoing Activity. - implementation "androidx.core:core:1.16.0" + implementation "androidx.core:core:1.17.0" } def props = new Properties() From 32a81d82a2eab4d87e446b3c1276e23fda9e0e9e Mon Sep 17 00:00:00 2001 From: Gerhard Olsson <6248932+gerhardol@users.noreply.github.com> Date: Mon, 5 Jan 2026 20:40:19 +0100 Subject: [PATCH 5/6] feat: build with GitHub Action (#1303) --- .github/workflows/actions.yml | 118 ++++++++++++++++++ .travis.yml | 35 ------ app/build.gradle | 66 +++------- app/lint-baseline.xml | 31 +---- app/src/main/org/runnerup/db/DBHelper.java | 6 +- .../runnerup/export/DropboxSynchronizer.java | 4 +- .../runnerup/export/RunalyzeSynchronizer.java | 7 +- .../org/runnerup/view/DetailActivity.java | 12 +- .../org/runnerup/view/SettingsFragment.java | 2 +- build.gradle | 51 +++++++- common/build.gradle | 4 + common/lint-baseline.xml | 7 -- common/lint.xml | 3 + gradle.properties | 6 +- hrdevice/build.gradle | 4 + hrdevice/lint-baseline.xml | 2 +- wear/build.gradle | 4 + wear/lint-baseline.xml | 2 +- 18 files changed, 222 insertions(+), 142 deletions(-) create mode 100644 .github/workflows/actions.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml new file mode 100644 index 000000000..9faa23d7c --- /dev/null +++ b/.github/workflows/actions.yml @@ -0,0 +1,118 @@ +name: Android CI + +on: + push: + branches: + - master + - test/** + pull_request: + types: [opened, synchronize, reopened] + +env: + ANDROID_API: 36.1 + ANDROID_BUILD_TOOLS: 36.1.0 + ADB_INSTALL_TIMEOUT: 5 + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + cache: 'gradle' + + - name: Cache Gradle Build Cache + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches/build-cache-* + key: ${{ runner.os }}-gradle-build-cache-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-gradle-build-cache- + + - name: Restore cache for Git LFS Objects + id: lfs-cache + uses: actions/cache@v4 + with: + path: .git/lfs + key: ${{ runner.os }}-lfs-${{ hashFiles('.git/lfs/objects/**') }} + restore-keys: ${{ runner.os }}-lfs- + + - name: Git LFS Pull + run: git lfs pull + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Install Android SDK components + run: | + sdkmanager "tools" + sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}" + sdkmanager "platforms;android-${ANDROID_API}" + sdkmanager "extras;android;m2repository" + sdkmanager "extras;google;m2repository" + sdkmanager "extras;google;google_play_services" + + - name: Prepare builddir + run: | + echo "${{ secrets.MAPBOX }}" > $GITHUB_WORKSPACE/mapbox.properties + echo "${{ secrets.DROPBOX }}" > $GITHUB_WORKSPACE/dropbox.properties + echo "${{ secrets.RUNALYZE }}" > $GITHUB_WORKSPACE/runalyze.properties + chmod +x gradlew + + - name: Build bundle + run: ./gradlew :app:bundleLatestRelease :wear:bundleRelease + + - name: Upload build logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: build-bundle + # possibly include: app/build/outputs/bundle/latestRelease/ wear/build/outputs/bundle/release/ + path: | + **/build/outputs/logs/ + + - name: Test + run: ./gradlew testBuildTypesUnitTest :app:testLatestDebugUnitTest testDebugUnitTest + + - name: Upload test logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-logs + path: | + **/build/reports/tests/ + + - name: Lint latest release + run: ./gradlew :app:lintLatestRelease :wear:lintRelease :hrdevice:lintRelease :common:lintRelease + + - name: Upload lint logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: lint-logs + path: | + **/build/reports/lint-results-release.html + **/build/reports/lint-results-latestRelease.html + + - name: Build F-Droid + run: | + rm $GITHUB_WORKSPACE/mapbox.properties + # For special build steps, see https://gitlab.com/fdroid/fdroiddata.git metadata/org.runnerup.free.yml + rm -rf wear ANT-Android-SDKs $GITHUB_WORKSPACE/dropbox.properties $GITHUB_WORKSPACE/runalyze.properties + sed -i -e '/play-services/d' -e '/mapboxsdk/d' -e '/api.mapbox.com/d' app/build.gradle + sed -i -e '/wearable/d' common/build.gradle + ./gradlew clean :app:assembleLatestRelease + + - name: Upload F-Droid logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: fdroid-logs + path: | + build/reports/problems/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9fa069636..000000000 --- a/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -env: - global: - - ANDROID_API=35 - - ANDROID_BUILD_TOOLS=36.0.0 - - ADB_INSTALL_TIMEOUT=5 -language: android -jdk: -- oraclejdk8 -cache: - directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ -before_cache: -- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock -- rm -f $HOME/.gradle/caches/*/classAnalysis/cache.properties.lock -- rm -f $HOME/.gradle/caches/*/jarSnapshots/cache.properties.lock -- rm -fr $HOME/.gradle/caches/*/plugin-resolution/ -android: - components: - - tools #latest for "builtin" sdk tools (24.4.1 in Android-25) - #To update SDK Tools to latest, another update is required - #- tools #latest, 26.1.1 as of 2018-10-07 - #- platform-tools #latest, 28.0.1 as of 2018-10-07 - - build-tools-$ANDROID_BUILD_TOOLS - - android-$ANDROID_API - - extra-android-m2repository - - extra-google-m2repository - - extra-google-google_play_services -notifications: - email: false -script: -- ./gradlew wear:lintRelease -- ./gradlew app:lintLatestRelease -- ./gradlew app:assembleLatestRelease -- ./gradlew app:test diff --git a/app/build.gradle b/app/build.gradle index 316bc6695..5144b72a6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,7 +29,7 @@ android { } if (rootProject.ext.noMap) { java.srcDirs += ['src/nomap'] - } else if (rootProject.ext.useMapBox) { + } else if (rootProject.ext.mapboxEnabled) { java.srcDirs += ['src/mapbox'] } else { java.srcDirs += ['src/osmdroid'] @@ -102,6 +102,10 @@ android { showAll = true //textOutput = 'stdout' textReport = true + // Treat all warnings as errors + warningsAsErrors = true + // Halt the build if any errors are found + abortOnError = true } bundle { language { @@ -122,7 +126,7 @@ repositories { google() mavenCentral() //MapBox GraphView maven { url = "https://oss.sonatype.org/content/groups/public/" } //pebblekit - if (rootProject.ext.useMapBox) { + if (rootProject.ext.mapboxEnabled) { maven { url = 'https://api.mapbox.com/downloads/v2/releases/maven' authentication { @@ -178,7 +182,7 @@ dependencies { // MapBox uses telemetry, without Play there may be exceptions from mapbox (OK to ignore) latestImplementation "com.google.android.gms:play-services-location:${rootProject.ext.googlePlayServicesVersion}" } - if (rootProject.ext.useMapBox) { + if (rootProject.ext.mapboxEnabled) { //noinspection GradleDependency latestImplementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.6.2' latestImplementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' @@ -202,6 +206,7 @@ allprojects { } def props = new Properties() +// For locally signed builds only, Google Play signs the bundle if (rootProject.file("release.properties").exists()) { props.load(new FileInputStream(rootProject.file("release.properties"))) @@ -215,54 +220,17 @@ if (rootProject.file("release.properties").exists()) { } android.applicationVariants.configureEach { - // Note: As a minimum extra security at least obfuscate the strings with Proguard - if (rootProject.ext.noMap) { - buildConfigField 'boolean', 'USING_OSMDROID', "false" - buildConfigField 'int', 'MAPBOX_ENABLED', "0" - buildConfigField 'String', 'MAPBOX_ACCESS_TOKEN', '""' - } else if (rootProject.ext.useMapBox) { - // https://www.mapbox.com/account/ - props.load(new FileInputStream(rootProject.file("mapbox.properties"))) - buildConfigField 'int', 'MAPBOX_ENABLED', "1" - buildConfigField 'String', 'MAPBOX_ACCESS_TOKEN', props.mapboxAccessToken + buildConfigField 'boolean', 'MAPBOX_ENABLED', "${rootProject.ext.mapboxEnabled}" + buildConfigField 'String', 'MAPBOX_ACCESS_TOKEN', "\"${rootProject.ext.mapboxAccessToken}\"" + buildConfigField 'boolean', 'OSMDROID_ENABLED', "${rootProject.ext.osmdroidEnabled}" - buildConfigField 'boolean', 'USING_OSMDROID', "false" - } else { - buildConfigField 'int', 'MAPBOX_ENABLED', "0" - buildConfigField 'String', 'MAPBOX_ACCESS_TOKEN', '""' - buildConfigField 'boolean', 'USING_OSMDROID', "true" - } + buildConfigField 'boolean', 'RUNALYZE_ENABLED', "${rootProject.ext.runalyzeEnabled}" + buildConfigField 'String', 'RUNALYZE_ID', "\"${rootProject.ext.runalyzeId}\"" + buildConfigField 'String', 'RUNALYZE_SECRET', "\"${rootProject.ext.runalyzeSecret}\"" - if (rootProject.file("runalyze.properties").exists()) { - // Contact Runalyze team at https://forum.runalyze.com/ - props.load(new FileInputStream(rootProject.file("runalyze.properties"))) - buildConfigField 'int', 'RUNALYZE_ENABLED', "1" - buildConfigField 'String', 'RUNALYZE_ID', props.CLIENT_ID - buildConfigField 'String', 'RUNALYZE_SECRET', props.CLIENT_SECRET - } else { - // Demo, connect to testing.runalyze.com - buildConfigField 'int', 'RUNALYZE_ENABLED', "0" - buildConfigField 'String', 'RUNALYZE_ID', '"8_2jx5jt9r39ic40ooc80c8c0884okgk0owsowg808c4csg8ko8g"' - buildConfigField 'String', 'RUNALYZE_SECRET', '"1v7d6nwe1v9c8skok44g0gc8cc04cc0wwwo8swwgckoogwsww4"' - } - - if (rootProject.file("dropbox.properties").exists()) { - // Create an app at https://www.dropbox.com/developers/apps/ - // Dropbox API, App folder -> create app - // Enable additional users, Redirect URI:http://localhost:8080/runnerup/dropbox, Disallow implicit grant - // Set branding icon - // Create dropbox.properties with two lines: - // CLIENT_ID="replace_dropbox_id" - // CLIENT_SECRET="replace_dropbox_secret" - props.load(new FileInputStream(rootProject.file("dropbox.properties"))) - buildConfigField 'int', 'DROPBOX_ENABLED', "1" - buildConfigField 'String', 'DROPBOX_ID', props.CLIENT_ID - buildConfigField 'String', 'DROPBOX_SECRET', props.CLIENT_SECRET - } else { - buildConfigField 'int', 'DROPBOX_ENABLED', "0" - buildConfigField 'String', 'DROPBOX_ID', "null" - buildConfigField 'String', 'DROPBOX_SECRET', "null" - } + buildConfigField 'boolean', 'DROPBOX_ENABLED', "${rootProject.ext.dropboxEnabled}" + buildConfigField 'String', 'DROPBOX_ID', "\"${rootProject.ext.dropboxId}\"" + buildConfigField 'String', 'DROPBOX_SECRET', "\"${rootProject.ext.dropboxSecret}\"" } //Based on an example from https://developer.android.com/studio/build/configure-apk-splits.html diff --git a/app/lint-baseline.xml b/app/lint-baseline.xml index 5cb214c6d..9cb0b5202 100644 --- a/app/lint-baseline.xml +++ b/app/lint-baseline.xml @@ -1,16 +1,5 @@ - - - - - + @@ -63,24 +52,10 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - - - - - - - - 0 ? "https://runalyze.com" : "https://testing.runalyze.com"; + BuildConfig.RUNALYZE_ENABLED ? "https://runalyze.com" : "https://testing.runalyze.com"; private static final String PUBLIC_URL = BASE_URL; private static final String UPLOAD_URL = BASE_URL + "/api/v1/activities/uploads"; @@ -67,7 +68,7 @@ public class RunalyzeSynchronizer extends DefaultSynchronizer implements OAuth2S private final PathSimplifier simplifier; RunalyzeSynchronizer(PathSimplifier simplifier) { - if (ENABLED == 0) { + if (!ENABLED) { Log.w(NAME, "No client id configured in this build"); } this.simplifier = simplifier; diff --git a/app/src/main/org/runnerup/view/DetailActivity.java b/app/src/main/org/runnerup/view/DetailActivity.java index fc260237a..27e69666a 100644 --- a/app/src/main/org/runnerup/view/DetailActivity.java +++ b/app/src/main/org/runnerup/view/DetailActivity.java @@ -17,7 +17,6 @@ package org.runnerup.view; -import static org.runnerup.BuildConfig.USING_OSMDROID; import static org.runnerup.content.ActivityProvider.GPX_MIME; import static org.runnerup.content.ActivityProvider.TCX_MIME; @@ -136,7 +135,7 @@ public class DetailActivity extends AppCompatActivity implements Constants { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (USING_OSMDROID || BuildConfig.MAPBOX_ENABLED > 0) { + if (BuildConfig.OSMDROID_ENABLED || BuildConfig.MAPBOX_ENABLED) { // MapBox or Osmdroid, set mapWrapper. MapWrapper.start(this); } @@ -210,7 +209,7 @@ public int preSetValue(int newValue) throws IllegalArgumentException { }); notes = findViewById(R.id.notes_text); - if (USING_OSMDROID || BuildConfig.MAPBOX_ENABLED > 0) { + if (BuildConfig.OSMDROID_ENABLED || BuildConfig.MAPBOX_ENABLED) { Object mapView = findViewById(R.id.mapview); mapWrapper = new MapWrapper(this, mDB, mID, formatter, mapView); mapWrapper.onCreate(savedInstanceState); @@ -235,7 +234,7 @@ public int preSetValue(int newValue) throws IllegalArgumentException { tabSpec.setContent(R.id.tab_lap); th.addTab(tabSpec); - if (USING_OSMDROID || BuildConfig.MAPBOX_ENABLED > 0) { + if (BuildConfig.OSMDROID_ENABLED || BuildConfig.MAPBOX_ENABLED) { tabSpec = th.newTabSpec("map"); tabSpec.setIndicator( WidgetUtil.createHoloTabIndicator(this, getString(org.runnerup.common.R.string.Map))); @@ -317,8 +316,9 @@ public WindowInsetsCompat onApplyWindowInsets( LinearLayout graphTabLayout = findViewById(R.id.tab_graph); LinearLayout hrzonesBarLayout = findViewById(R.id.hrzonesBarLayout); boolean use_distance_as_x = !Sport.isWithoutGps(sport.getValueInt()); - graphWrapper = new GraphWrapper(this, graphTabLayout, hrzonesBarLayout, - formatter, mDB, mID, use_distance_as_x); + // variable not needed + new GraphWrapper(this, graphTabLayout, hrzonesBarLayout, + formatter, mDB, mID, use_distance_as_x); if (this.mode == MODE_SAVE) { resumeButton.setOnClickListener(resumeButtonClick); diff --git a/app/src/main/org/runnerup/view/SettingsFragment.java b/app/src/main/org/runnerup/view/SettingsFragment.java index dfc5caff7..8c36d2d62 100644 --- a/app/src/main/org/runnerup/view/SettingsFragment.java +++ b/app/src/main/org/runnerup/view/SettingsFragment.java @@ -14,7 +14,7 @@ public class SettingsFragment extends PreferenceFragmentCompat { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.settings, rootKey); - if (BuildConfig.MAPBOX_ENABLED == 0) { + if (!BuildConfig.MAPBOX_ENABLED) { Preference pref = findPreference("map_preferencescreen"); pref.setEnabled(false); } diff --git a/build.gradle b/build.gradle index 7ce75434f..a7b0fd8c1 100644 --- a/build.gradle +++ b/build.gradle @@ -15,8 +15,8 @@ repositories { project.ext { //Common settings for most builds //Note that Android Studio does not know about the 'ext' module and will warn - buildToolsVersion = '36.1.0' //Update Travis manually - compileSdk = 36.1 //Update Travis manually + buildToolsVersion = '36.1.0' // also .github/workflows/actions.yml + compileSdk = 36.1 // also .github/workflows/actions.yml targetSdk = 36.1 minSdk = 21 @@ -39,11 +39,52 @@ project.ext { // F-Droid builds only allow free software (wear dir deleted at builds) allowNonFree = !project.hasProperty('org.runnerup.free') && rootProject.file("wear").exists() enableWear = !project.hasProperty('org.runnerup.wear.disable') && rootProject.file("wear").exists() - - // Use or not use mapbox. - useMapBox = allowNonFree && rootProject.file("mapbox.properties").exists() noMap = project.hasProperty('org.runnerup.nomap') + // get tokens, also required to set buildDirs + + mapboxAccessToken = "" + def props = new Properties() + if (!noMap && allowNonFree && rootProject.file("mapbox.properties").exists()) { + // https://www.mapbox.com/account/ + props.load(new FileInputStream(rootProject.file("mapbox.properties"))) + mapboxAccessToken = props.getProperty("mapboxAccessToken") ?: "" + } + mapboxEnabled = !mapboxAccessToken.isEmpty() + osmdroidEnabled = !noMap && !mapboxEnabled + + runalyzeId = "" + if (rootProject.file("runalyze.properties").exists()) { + // Contact Runalyze team at https://forum.runalyze.com/ + props.load(new FileInputStream(rootProject.file("runalyze.properties"))) + runalyzeEnabled = true + runalyzeId = props.getProperty("CLIENT_ID") ?: "" + runalyzeSecret = props.getProperty("CLIENT_SECRET") ?: "" + } + if (runalyzeId.isEmpty() || runalyzeSecret.isEmpty()) { + // Demo, with runalyzeEnabled set to false connect to testing.runalyze.com + runalyzeEnabled = false + runalyzeId = "8_2jx5jt9r39ic40ooc80c8c0884okgk0owsowg808c4csg8ko8g" + runalyzeSecret = "1v7d6nwe1v9c8skok44g0gc8cc04cc0wwwo8swwgckoogwsww4" + } + + dropboxEnabled = false + dropboxId = "" + dropboxSecret = "" + if (rootProject.file("dropbox.properties").exists()) { + // Create an app at https://www.dropbox.com/developers/apps/ + // Dropbox API, App folder -> create app + // Enable additional users, Redirect URI:http://localhost:8080/runnerup/dropbox, Disallow implicit grant + // Set branding icon + // Create dropbox.properties with two lines: + // CLIENT_ID="replace_dropbox_id" + // CLIENT_SECRET="replace_dropbox_secret" + props.load(new FileInputStream(rootProject.file("dropbox.properties"))) + dropboxEnabled = true + dropboxId = props.getProperty("CLIENT_ID") ?: "" + dropboxSecret = props.getProperty("CLIENT_SECRET") ?: "" + } + // Note: AntPlus may have to be downloaded explicitly due to licensing // Therefore, the .aar file may not be redistributed in the RU repo antPlusLibPath = "$rootDir/ANT-Android-SDKs/ANT+_Android_SDK/API" diff --git a/common/build.gradle b/common/build.gradle index 2f2462d41..7488ee5ff 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -43,6 +43,10 @@ android { lintConfig = file('lint.xml') //textOutput = 'stdout' textReport = true + // Treat all warnings as errors + warningsAsErrors = true + // Halt the build if any errors are found + abortOnError = true } namespace = 'org.runnerup.common' buildFeatures { diff --git a/common/lint-baseline.xml b/common/lint-baseline.xml index 51f09c8eb..b689d67e0 100644 --- a/common/lint-baseline.xml +++ b/common/lint-baseline.xml @@ -12,11 +12,4 @@ column="17"/> - - - - diff --git a/common/lint.xml b/common/lint.xml index c4b210183..d7f33b42b 100644 --- a/common/lint.xml +++ b/common/lint.xml @@ -5,4 +5,7 @@ + + + diff --git a/gradle.properties b/gradle.properties index 0a91919ef..cdeb25fcc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,5 @@ # R8 is not displaying warnings for configuration issues, proguard may be required # Build with ./gradlew app:minifyLatestReleaseWithProguard -#android.enableR8=false android.enableJetifier=true android.useAndroidX=true org.gradle.caching = true @@ -10,8 +9,11 @@ org.gradle.vfs.watch = true org.gradle.unsafe.configuration-cache=true android.nonTransitiveRClass=true android.nonFinalResIds=true +org.gradle.jvmargs=-Xmx4096m +-XX:MaxMetaspaceSize=1024m +-Dfile.encoding=UTF-8 + # org.runnerup.free=true -# org.gradle.jvmargs=-Xmx4096M # org.runnerup.hr.disableAntPlus=true # org.runnerup.wear.disable=true diff --git a/hrdevice/build.gradle b/hrdevice/build.gradle index 73a0c5749..877d1c0d1 100644 --- a/hrdevice/build.gradle +++ b/hrdevice/build.gradle @@ -31,6 +31,10 @@ android { showAll = true //textOutput = 'stdout' textReport = true + // Treat all warnings as errors + warningsAsErrors = true + // Halt the build if any errors are found + abortOnError = true } defaultConfig { minSdk = rootProject.ext.minSdk diff --git a/hrdevice/lint-baseline.xml b/hrdevice/lint-baseline.xml index 375963cc0..f3c60b6dc 100644 --- a/hrdevice/lint-baseline.xml +++ b/hrdevice/lint-baseline.xml @@ -1,5 +1,5 @@ - + - + From 8e40a42b88098ad825b42498326850925712d407 Mon Sep 17 00:00:00 2001 From: Gerhard Olsson Date: Tue, 13 Jan 2026 23:15:40 +0100 Subject: [PATCH 6/6] fix: special lint config if no mapbox key --- .github/workflows/actions.yml | 1 + app/build.gradle | 6 ++- app/lint-osmdroid.xml | 48 +++++++++++++++++++ app/lint.xml | 1 + .../tracker/component/TrackerGPS.java | 13 +++-- 5 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 app/lint-osmdroid.xml diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 9faa23d7c..8065d0c82 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -60,6 +60,7 @@ jobs: - name: Prepare builddir run: | + # secrets are only available for collabrators, other will build with OsmDroid (but a few more options than F-Droid still) echo "${{ secrets.MAPBOX }}" > $GITHUB_WORKSPACE/mapbox.properties echo "${{ secrets.DROPBOX }}" > $GITHUB_WORKSPACE/dropbox.properties echo "${{ secrets.RUNALYZE }}" > $GITHUB_WORKSPACE/runalyze.properties diff --git a/app/build.gradle b/app/build.gradle index 5144b72a6..401c321e3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -98,7 +98,11 @@ android { lint { baseline = file('lint-baseline.xml') checkReleaseBuilds = true - lintConfig = file('lint.xml') + if (mapboxEnabled) { + lintConfig = file('lint.xml') + } else { + lintConfig = file('lint-osmdroid.xml') + } showAll = true //textOutput = 'stdout' textReport = true diff --git a/app/lint-osmdroid.xml b/app/lint-osmdroid.xml new file mode 100644 index 000000000..2c50ab3b6 --- /dev/null +++ b/app/lint-osmdroid.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/lint.xml b/app/lint.xml index 4f935c9b0..743715ebc 100644 --- a/app/lint.xml +++ b/app/lint.xml @@ -69,4 +69,5 @@ + diff --git a/app/src/main/org/runnerup/tracker/component/TrackerGPS.java b/app/src/main/org/runnerup/tracker/component/TrackerGPS.java index 870b7f555..ca04ded20 100644 --- a/app/src/main/org/runnerup/tracker/component/TrackerGPS.java +++ b/app/src/main/org/runnerup/tracker/component/TrackerGPS.java @@ -28,6 +28,8 @@ import android.location.LocationManager; import android.os.Handler; import android.text.TextUtils; + +import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.preference.PreferenceManager; import org.runnerup.R; @@ -116,11 +118,16 @@ private Integer parseAndFixInteger( return Integer.parseInt(s); } - static Location getLastKnownLocation(LocationManager lm) { + static Location getLastKnownLocation(LocationManager lm, Context context) { String[] list = {GPS_PROVIDER, NETWORK_PROVIDER, PASSIVE_PROVIDER}; Location lastLocation = null; for (String s : list) { - Location tmp = lm.getLastKnownLocation(s); + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // User has deactivated location permission during the workout. + continue; + } + Location tmp = lm.getLastKnownLocation(s); if (tmp == null) { continue; } @@ -154,7 +161,7 @@ public ResultCode onConnecting(final Callback callback, Context context) { var lm = locationManager; SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); frequency_ms = parseAndFixInteger(preferences, R.string.pref_pollInterval, "1000", context); - mLastLocation = getLastKnownLocation(lm); + mLastLocation = getLastKnownLocation(lm, context); if (!mWithoutGps) { Integer frequency_meters = parseAndFixInteger(preferences, R.string.pref_pollDistance, "0", context);