diff --git a/android/src/main/java/app/capgo/capacitor/camera/preview/CameraPreview.java b/android/src/main/java/app/capgo/capacitor/camera/preview/CameraPreview.java index 37e1410a..f6a5a9e1 100644 --- a/android/src/main/java/app/capgo/capacitor/camera/preview/CameraPreview.java +++ b/android/src/main/java/app/capgo/capacitor/camera/preview/CameraPreview.java @@ -108,6 +108,7 @@ protected void handleOnDestroy() { cameraXView = null; } lastSessionConfig = null; + restoreSystemUiForToBackMode(getBridge().getActivity()); } private CameraSessionConfiguration lastSessionConfig; @@ -136,6 +137,9 @@ protected void handleOnDestroy() { private Drawable originalWindowBackground; private Float originalWebViewAlpha; private Drawable originalWebViewParentBackground; + private Integer originalStatusBarColor; + private Integer originalNavigationBarColor; + private Boolean originalNavigationBarContrastEnforced; private boolean isCameraPermissionDialogShowing = false; @PluginMethod @@ -433,6 +437,7 @@ public void stop(final PluginCall call) { originalWindowBackground = null; } restoreWebViewVisualState(); + restoreSystemUiForToBackMode(getBridge().getActivity()); call.resolve(); }); } @@ -947,6 +952,7 @@ private void startCamera(final PluginCall call) { getBridge() .getActivity() .runOnUiThread(() -> { + lockSystemUiForToBackMode(getBridge().getActivity(), toBack); // Ensure transparent background when preview is behind the WebView (Android 10 fix) if (toBack) { try { @@ -1531,6 +1537,70 @@ private boolean isMiuiDevice() { return manufacturer.contains("xiaomi") || brand.contains("xiaomi") || brand.contains("redmi") || brand.contains("poco"); } + private int toOpaqueColor(int color) { + return Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)); + } + + private void lockSystemUiForToBackMode(Activity activity, boolean toBack) { + if (activity == null) { + return; + } + if (!toBack) { + return; + } + + try { + if (originalStatusBarColor == null) { + originalStatusBarColor = activity.getWindow().getStatusBarColor(); + } + if (originalNavigationBarColor == null) { + originalNavigationBarColor = activity.getWindow().getNavigationBarColor(); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && originalNavigationBarContrastEnforced == null) { + originalNavigationBarContrastEnforced = activity.getWindow().isNavigationBarContrastEnforced(); + } + + int statusBarColor = toOpaqueColor(originalStatusBarColor != null ? originalStatusBarColor : Color.BLACK); + int navigationBarColor = toOpaqueColor(originalNavigationBarColor != null ? originalNavigationBarColor : Color.BLACK); + + activity.getWindow().setStatusBarColor(statusBarColor); + activity.getWindow().setNavigationBarColor(navigationBarColor); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + activity.getWindow().setNavigationBarContrastEnforced(false); + } + } catch (Exception e) { + Log.w(TAG, "Failed to lock system UI colors for toBack mode", e); + } + } + + private void restoreSystemUiForToBackMode(Activity activity) { + final Integer statusBarColor = originalStatusBarColor; + final Integer navigationBarColor = originalNavigationBarColor; + final Boolean navigationBarContrastEnforced = originalNavigationBarContrastEnforced; + originalStatusBarColor = null; + originalNavigationBarColor = null; + originalNavigationBarContrastEnforced = null; + + if (activity == null) { + return; + } + + activity.runOnUiThread(() -> { + try { + if (statusBarColor != null) { + activity.getWindow().setStatusBarColor(statusBarColor); + } + if (navigationBarColor != null) { + activity.getWindow().setNavigationBarColor(navigationBarColor); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && navigationBarContrastEnforced != null) { + activity.getWindow().setNavigationBarContrastEnforced(navigationBarContrastEnforced); + } + } catch (Exception ignored) {} + }); + } + private void applyTransparentBackgroundsForToBack() { if (!isToBackMode()) { return; @@ -1801,6 +1871,7 @@ public void onCameraStartError(String message) { } } restoreWebViewVisualState(); + restoreSystemUiForToBackMode(getBridge().getActivity()); } @PluginMethod