Skip to content

Commit ebfe32b

Browse files
committed
Added option to enable / disable logging, centralized all logging everywhere.
1 parent 5fba61c commit ebfe32b

File tree

14 files changed

+259
-102
lines changed

14 files changed

+259
-102
lines changed

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/MainApplication.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.zebra.ai_multibarcodes_capture;
22

33
import android.app.Application;
4+
import android.content.Context;
45
import android.content.Intent;
56
import android.content.IntentFilter;
7+
import android.content.SharedPreferences;
68
import android.os.Handler;
79
import android.os.Looper;
810
import android.util.Log;
@@ -11,6 +13,7 @@
1113
import com.zebra.criticalpermissionshelper.CriticalPermissionsHelper;
1214
import com.zebra.criticalpermissionshelper.EPermissionType;
1315
import com.zebra.criticalpermissionshelper.IResultCallbacks;
16+
import com.zebra.ai_multibarcodes_capture.helpers.Constants;
1417
import com.zebra.ai_multibarcodes_capture.helpers.LogUtils;
1518
import com.zebra.ai_multibarcodes_capture.managedconfig.ManagedConfigurationReceiver;
1619

@@ -45,6 +48,9 @@ public void onCreate() {
4548
// Initialize LogUtils for feedback reporting
4649
LogUtils.initialize(this);
4750

51+
// Load logging enabled setting from SharedPreferences and apply it to LogUtils
52+
loadLoggingEnabledSetting();
53+
4854
// Register managed configuration receiver dynamically (required for Android 8.0+)
4955
registerManagedConfigurationReceiver();
5056

@@ -180,4 +186,17 @@ public void onTerminate() {
180186
}
181187
}
182188
}
189+
190+
/**
191+
* Loads the logging enabled setting from SharedPreferences and applies it to LogUtils.
192+
* This ensures logging state is restored when the app starts.
193+
*/
194+
private void loadLoggingEnabledSetting() {
195+
SharedPreferences sharedPreferences = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
196+
boolean loggingEnabled = sharedPreferences.getBoolean(
197+
Constants.SHARED_PREFERENCES_LOGGING_ENABLED,
198+
Constants.SHARED_PREFERENCES_LOGGING_ENABLED_DEFAULT
199+
);
200+
LogUtils.setLoggingEnabled(loggingEnabled);
201+
}
183202
}

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/barcodedecoder/BarcodeAnalyzer.java

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.zebra.ai.vision.detector.BarcodeDecoder;
1111
import com.zebra.ai.vision.detector.ImageData;
1212
import com.zebra.ai.vision.entity.BarcodeEntity;
13+
import com.zebra.ai_multibarcodes_capture.helpers.LogUtils;
1314

1415
import java.io.ByteArrayOutputStream;
1516
import java.nio.ByteBuffer;
@@ -151,11 +152,11 @@ public void analyze(@NonNull ImageProxy image) {
151152

152153
Future<?> future = executorService.submit(() -> {
153154
try {
154-
Log.d(TAG, "Starting image analysis" + (currentCropRegion != null ? " with crop region" : ""));
155+
LogUtils.d(TAG, "Starting image analysis" + (currentCropRegion != null ? " with crop region" : ""));
155156

156157
// Get the rotation from the ImageProxy
157158
int rotationDegrees = image.getImageInfo().getRotationDegrees();
158-
Log.d(TAG, "Image rotation degrees: " + rotationDegrees);
159+
LogUtils.d(TAG, "Image rotation degrees: " + rotationDegrees);
159160

160161
// Store the rotation for the activity to use when transforming bounding boxes
161162
lastImageRotationDegrees = rotationDegrees;
@@ -171,10 +172,10 @@ public void analyze(@NonNull ImageProxy image) {
171172
// 2. We want bounding boxes in raw image space (so we can add raw crop offset)
172173
// 3. The activity uses lastImageRotationDegrees to transform to effective space
173174
imageData = ImageData.fromBitmap(croppedBitmap, 0);
174-
Log.d(TAG, "Processing grayscale cropped image: " + croppedBitmap.getWidth() + "x" + croppedBitmap.getHeight() + " (rotation=" + rotationDegrees + " stored for activity)");
175+
LogUtils.d(TAG, "Processing grayscale cropped image: " + croppedBitmap.getWidth() + "x" + croppedBitmap.getHeight() + " (rotation=" + rotationDegrees + " stored for activity)");
175176
} else {
176177
// Fallback to full image if cropping fails
177-
Log.w(TAG, "Cropping failed, falling back to full image");
178+
LogUtils.w(TAG, "Cropping failed, falling back to full image");
178179
imageData = ImageData.fromImageProxy(image);
179180
}
180181
} else {
@@ -236,17 +237,17 @@ public void analyze(@NonNull ImageProxy image) {
236237
isAnalyzing = true;
237238
})
238239
.exceptionally(ex -> {
239-
Log.e(TAG, "Error in completable future result " + ex.getMessage());
240+
LogUtils.e(TAG, "Error in completable future result " + ex.getMessage());
240241
image.close();
241242
isAnalyzing = true;
242243
return null;
243244
});
244245
} catch (AIVisionSDKException e) {
245-
Log.e(TAG, Objects.requireNonNull(e.getMessage()));
246+
LogUtils.e(TAG, Objects.requireNonNull(e.getMessage()));
246247
image.close();
247248
isAnalyzing = true;
248249
} catch (Exception e) {
249-
Log.e(TAG, "Unexpected error during analysis: " + e.getMessage());
250+
LogUtils.e(TAG, "Unexpected error during analysis: " + e.getMessage());
250251
image.close();
251252
isAnalyzing = true;
252253
}
@@ -271,7 +272,7 @@ public void analyze(@NonNull ImageProxy image) {
271272
private Bitmap cropImageProxy(@NonNull ImageProxy image, @NonNull Rect cropRect) {
272273
try {
273274
if (image.getFormat() != ImageFormat.YUV_420_888) {
274-
Log.w(TAG, "Unsupported image format for cropping: " + image.getFormat());
275+
LogUtils.w(TAG, "Unsupported image format for cropping: " + image.getFormat());
275276
return null;
276277
}
277278

@@ -289,7 +290,7 @@ private Bitmap cropImageProxy(@NonNull ImageProxy image, @NonNull Rect cropRect)
289290
int cropHeight = bottom - top;
290291

291292
if (cropWidth <= 0 || cropHeight <= 0) {
292-
Log.w(TAG, "Invalid crop dimensions: " + cropWidth + "x" + cropHeight);
293+
LogUtils.w(TAG, "Invalid crop dimensions: " + cropWidth + "x" + cropHeight);
293294
return null;
294295
}
295296

@@ -303,7 +304,7 @@ private Bitmap cropImageProxy(@NonNull ImageProxy image, @NonNull Rect cropRect)
303304
}
304305

305306
} catch (Exception e) {
306-
Log.e(TAG, "Error cropping image: " + e.getMessage());
307+
LogUtils.e(TAG, "Error cropping image: " + e.getMessage());
307308
return null;
308309
}
309310
}
@@ -336,12 +337,12 @@ private Bitmap cropYuvToGrayscaleNative(@NonNull ImageProxy image, int cropLeft,
336337
return bitmap;
337338
} else {
338339
bitmap.recycle();
339-
Log.w(TAG, "Native grayscale conversion failed, falling back to Java");
340+
LogUtils.w(TAG, "Native grayscale conversion failed, falling back to Java");
340341
return cropYuvToGrayscaleJava(image, cropLeft, cropTop, cropWidth, cropHeight);
341342
}
342343

343344
} catch (Exception e) {
344-
Log.e(TAG, "Error in cropYuvToGrayscaleNative: " + e.getMessage());
345+
LogUtils.e(TAG, "Error in cropYuvToGrayscaleNative: " + e.getMessage());
345346
return cropYuvToGrayscaleJava(image, cropLeft, cropTop, cropWidth, cropHeight);
346347
}
347348
}
@@ -379,7 +380,7 @@ private Bitmap cropYuvToGrayscaleJava(@NonNull ImageProxy image, int cropLeft, i
379380
return bitmap;
380381

381382
} catch (Exception e) {
382-
Log.e(TAG, "Error in cropYuvToGrayscaleJava: " + e.getMessage());
383+
LogUtils.e(TAG, "Error in cropYuvToGrayscaleJava: " + e.getMessage());
383384
return null;
384385
}
385386
}
@@ -446,14 +447,14 @@ public void setCropRegion(@Nullable Rect region, int imageWidth, int imageHeight
446447
this.cropOffsetY = region.top;
447448
this.sourceImageWidth = imageWidth;
448449
this.sourceImageHeight = imageHeight;
449-
Log.d(TAG, "Crop region set: " + region.toString() + " for image " + imageWidth + "x" + imageHeight);
450+
LogUtils.d(TAG, "Crop region set: " + region.toString() + " for image " + imageWidth + "x" + imageHeight);
450451
} else {
451452
this.cropRegion = null;
452453
this.cropOffsetX = 0;
453454
this.cropOffsetY = 0;
454455
this.sourceImageWidth = 0;
455456
this.sourceImageHeight = 0;
456-
Log.d(TAG, "Crop region cleared");
457+
LogUtils.d(TAG, "Crop region cleared");
457458
}
458459
}
459460

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/barcodedecoder/BarcodeHandler.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.zebra.ai.vision.detector.InferencerOptions;
1212
import com.zebra.ai_multibarcodes_capture.helpers.EInferenceType;
1313
import com.zebra.ai_multibarcodes_capture.helpers.EModelInputSize;
14+
import com.zebra.ai_multibarcodes_capture.helpers.LogUtils;
1415

1516
import java.util.concurrent.ExecutorService;
1617
import java.util.concurrent.Executors;
@@ -211,22 +212,22 @@ public void initializeBarcodeDecoder() {
211212
barcodeDecoder = decoderInstance;
212213
barcodeAnalyzer = new BarcodeAnalyzer(callback, barcodeDecoder);
213214
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(context), barcodeAnalyzer);
214-
Log.d(TAG, "BarcodeDecoder() obj creation time =" + (System.currentTimeMillis() - m_Start) + " milli sec");
215+
LogUtils.d(TAG, "BarcodeDecoder() obj creation time =" + (System.currentTimeMillis() - m_Start) + " milli sec");
215216

216217
// Notify callback that analyzer is ready
217218
if (analyzerReadyCallback != null) {
218219
analyzerReadyCallback.onAnalyzerReady(barcodeAnalyzer);
219220
}
220221
}).exceptionally(e -> {
221222
if (e instanceof AIVisionSDKLicenseException) {
222-
Log.e(TAG, "AIVisionSDKLicenseException: Barcode Decoder object creation failed, " + e.getMessage());
223+
LogUtils.e(TAG, "AIVisionSDKLicenseException: Barcode Decoder object creation failed, " + e.getMessage());
223224
} else {
224-
Log.e(TAG, "Fatal error: decoder creation failed - " + e.getMessage());
225+
LogUtils.e(TAG, "Fatal error: decoder creation failed - " + e.getMessage());
225226
}
226227
return null;
227228
});
228229
} catch (AIVisionSDKException ex) {
229-
Log.e(TAG, "Model Loading: Barcode decoder returned with exception " + ex.getMessage());
230+
LogUtils.e(TAG, "Model Loading: Barcode decoder returned with exception " + ex.getMessage());
230231
}
231232
}
232233

@@ -290,7 +291,7 @@ public void stop() {
290291
executor.shutdownNow();
291292
if (barcodeDecoder != null) {
292293
barcodeDecoder.dispose();
293-
Log.d(TAG, "Barcode decoder is disposed");
294+
LogUtils.d(TAG, "Barcode decoder is disposed");
294295
barcodeDecoder = null;
295296
}
296297
}

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/barcodedecoder/NativeYuvProcessor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import android.graphics.Bitmap;
55
import android.util.Log;
66

7+
import com.zebra.ai_multibarcodes_capture.helpers.LogUtils;
8+
79
import java.nio.ByteBuffer;
810

911
/**
@@ -19,10 +21,10 @@ public class NativeYuvProcessor {
1921
try {
2022
System.loadLibrary("yuvprocessor");
2123
isNativeLibraryLoaded = true;
22-
Log.i(TAG, "Native YUV processor library loaded successfully");
24+
LogUtils.i(TAG, "Native YUV processor library loaded successfully");
2325
} catch (UnsatisfiedLinkError e) {
2426
isNativeLibraryLoaded = false;
25-
Log.e(TAG, "Failed to load native YUV processor library: " + e.getMessage());
27+
LogUtils.e(TAG, "Failed to load native YUV processor library: " + e.getMessage());
2628
}
2729
}
2830

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/filemanagement/BrowserActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public void onClick(View view) {
123123
java.lang.reflect.Method setForceIcons = menuPopupHelper.getClass().getDeclaredMethod("setForceShowIcon", boolean.class);
124124
setForceIcons.invoke(menuPopupHelper, true);
125125
} catch (Exception e) {
126-
Log.e("BrowserActivity", "Failed to force show icons in popup menu", e);
126+
LogUtils.e("BrowserActivity", "Failed to force show icons in popup menu", e);
127127
}
128128

129129
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/helpers/Constants.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ public class Constants {
239239
public static final String SHARED_PREFERENCES_DISPLAY_ANALYSIS_PER_SECOND = "SHARED_PREFERENCES_DISPLAY_ANALYSIS_PER_SECOND";
240240
public static final boolean SHARED_PREFERENCES_DISPLAY_ANALYSIS_PER_SECOND_DEFAULT = false;
241241

242+
// Logging Enabled preferences
243+
public static final String SHARED_PREFERENCES_LOGGING_ENABLED = "SHARED_PREFERENCES_LOGGING_ENABLED";
244+
public static final boolean SHARED_PREFERENCES_LOGGING_ENABLED_DEFAULT = false;
245+
242246
public static final int KEYCODE_BUTTON_R1 = 103;
243247
public static final int KEYCODE_SCAN = 10036;
244248
}

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/helpers/LogUtils.java

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class LogUtils {
3434
private static Context appContext;
3535
private static final String FEEDBACK_EMAIL = "[email protected]";
3636
private static boolean feedbackReportingEnabled = true;
37+
private static boolean loggingEnabled = false; // Disabled by default
3738

3839
/**
3940
* Initialize LogUtils with application context for feedback reporting
@@ -50,72 +51,120 @@ public static void setFeedbackReportingEnabled(boolean enabled) {
5051
feedbackReportingEnabled = enabled;
5152
}
5253

54+
/**
55+
* Enable or disable application logging.
56+
* When disabled, only feedback reporting (for errors) will still work.
57+
* @param enabled true to enable logging, false to disable
58+
*/
59+
public static void setLoggingEnabled(boolean enabled) {
60+
loggingEnabled = enabled;
61+
}
62+
63+
/**
64+
* Check if logging is currently enabled
65+
* @return true if logging is enabled, false otherwise
66+
*/
67+
public static boolean isLoggingEnabled() {
68+
return loggingEnabled;
69+
}
70+
5371
// Verbose logging
5472
public static void v(String TAG, String message) {
55-
Log.v(TAG, message);
73+
if (loggingEnabled) {
74+
Log.v(TAG, message);
75+
}
5676
}
5777

5878
public static void v(String TAG, String message, Throwable throwable) {
59-
Log.v(TAG, message, throwable);
79+
if (loggingEnabled) {
80+
Log.v(TAG, message, throwable);
81+
}
6082
}
6183

6284
// Debug logging
6385
public static void d(String TAG, String message) {
64-
Log.d(TAG, message);
86+
if (loggingEnabled) {
87+
Log.d(TAG, message);
88+
}
6589
}
6690

6791
public static void d(String TAG, String message, Throwable throwable) {
68-
Log.d(TAG, message, throwable);
92+
if (loggingEnabled) {
93+
Log.d(TAG, message, throwable);
94+
}
6995
}
7096

7197
// Info logging
7298
public static void i(String TAG, String message) {
73-
Log.i(TAG, message);
99+
if (loggingEnabled) {
100+
Log.i(TAG, message);
101+
}
74102
}
75103

76104
public static void i(String TAG, String message, Throwable throwable) {
77-
Log.i(TAG, message, throwable);
105+
if (loggingEnabled) {
106+
Log.i(TAG, message, throwable);
107+
}
78108
}
79109

80110
// Warning logging
81111
public static void w(String TAG, String message) {
82-
Log.w(TAG, message);
112+
if (loggingEnabled) {
113+
Log.w(TAG, message);
114+
}
83115
}
84116

85117
public static void w(String TAG, String message, Throwable throwable) {
86-
Log.w(TAG, message, throwable);
118+
if (loggingEnabled) {
119+
Log.w(TAG, message, throwable);
120+
}
87121
}
88122

89123
public static void w(String TAG, Throwable throwable) {
90-
Log.w(TAG, throwable);
124+
if (loggingEnabled) {
125+
Log.w(TAG, throwable);
126+
}
91127
}
92128

93129
// Error logging with automatic feedback reporting
130+
// Note: Feedback reporting works even when logging is disabled
94131
public static void e(String TAG, String message) {
95-
Log.e(TAG, message);
132+
if (loggingEnabled) {
133+
Log.e(TAG, message);
134+
}
135+
// Feedback reporting works regardless of loggingEnabled setting
96136
if (feedbackReportingEnabled && appContext != null) {
97137
reportErrorToFeedbackChannel(TAG, message, null);
98138
}
99139
}
100140

101141
public static void e(String TAG, String message, Throwable throwable) {
102-
Log.e(TAG, message, throwable);
142+
if (loggingEnabled) {
143+
Log.e(TAG, message, throwable);
144+
}
145+
// Feedback reporting works regardless of loggingEnabled setting
103146
if (feedbackReportingEnabled && appContext != null) {
104147
reportErrorToFeedbackChannel(TAG, message, throwable);
105148
}
106149
}
107150

108151
// What a Terrible Failure logging
109152
public static void wtf(String TAG, String message) {
110-
Log.wtf(TAG, message);
153+
if (loggingEnabled) {
154+
Log.wtf(TAG, message);
155+
}
111156
}
112157

113158
public static void wtf(String TAG, String message, Throwable throwable) {
114-
Log.wtf(TAG, message, throwable);
159+
if (loggingEnabled) {
160+
Log.wtf(TAG, message, throwable);
161+
}
115162
}
116163

117164
public static void wtf(String TAG, Throwable throwable) {
118-
Log.wtf(TAG, throwable);
165+
if (loggingEnabled) {
166+
Log.wtf(TAG, throwable);
167+
}
119168
}
120169

121170
// Utility methods for checking if log levels are enabled

0 commit comments

Comments
 (0)