Skip to content

Commit 073f77c

Browse files
authored
Address edge-to-edge Google Play Store warnings (#1205)
* Handle camera overlay window insets * Adopt AndroidX edge-to-edge helpers
1 parent efacb8d commit 073f77c

File tree

5 files changed

+148
-9
lines changed

5 files changed

+148
-9
lines changed

app/android/app/src/main/java/com/proofofpassportapp/MainActivity.kt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ package com.proofofpassportapp
55
import android.content.Intent
66
import android.os.Bundle
77
import android.util.Log
8-
import android.content.pm.ActivityInfo
9-
import androidx.core.view.WindowCompat
8+
import android.graphics.Color
9+
import androidx.activity.SystemBarStyle
10+
import androidx.activity.enableEdgeToEdge
1011
import com.facebook.react.ReactActivity
1112
import com.facebook.react.ReactActivityDelegate
1213
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
@@ -43,9 +44,12 @@ class MainActivity : ReactActivity() {
4344
// Prevent fragment state restoration to avoid react-native-screens crash
4445
// See: https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-424704978
4546
super.onCreate(null)
46-
// Ensure edge-to-edge is enabled consistently across Android versions
47-
// Android 15 enables by default; on earlier versions, opt-in for immersive layouts
48-
WindowCompat.setDecorFitsSystemWindows(window, false)
47+
// Ensure edge-to-edge is enabled consistently across Android versions using
48+
// the AndroidX helper so deprecated window color APIs are avoided.
49+
enableEdgeToEdge(
50+
statusBarStyle = SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT),
51+
navigationBarStyle = SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT)
52+
)
4953
// Allow system to manage orientation for large screens
5054
}
5155
}

app/android/app/src/main/java/com/proofofpassportapp/ui/CameraMLKitFragment.kt

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ import android.graphics.Color
2828
import android.os.Bundle
2929
import android.os.Handler
3030
import android.os.Looper
31-
import android.util.Log
3231
import android.view.LayoutInflater
3332
import android.view.View
3433
import android.view.ViewGroup
3534
import android.widget.Toast
35+
import androidx.core.view.ViewCompat
36+
import androidx.core.view.WindowInsetsCompat
37+
import androidx.core.view.doOnAttach
3638
import com.google.mlkit.vision.text.Text
3739

3840

@@ -77,6 +79,47 @@ class CameraMLKitFragment(cameraMLKitCallback: CameraMLKitCallback) : CameraFrag
7779

7880
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
7981
super.onViewCreated(view, savedInstanceState)
82+
val fragmentBinding = binding ?: return
83+
val statusTop = fragmentBinding.statusViewTop
84+
val statusBottom = fragmentBinding.statusViewBottom
85+
val initialTopStart = ViewCompat.getPaddingStart(statusTop)
86+
val initialTopPadding = statusTop.paddingTop
87+
val initialTopEnd = ViewCompat.getPaddingEnd(statusTop)
88+
val initialTopBottom = statusTop.paddingBottom
89+
val initialBottomStart = ViewCompat.getPaddingStart(statusBottom)
90+
val initialBottomTop = statusBottom.paddingTop
91+
val initialBottomEnd = ViewCompat.getPaddingEnd(statusBottom)
92+
val initialBottomPadding = statusBottom.paddingBottom
93+
94+
ViewCompat.setOnApplyWindowInsetsListener(fragmentBinding.root) { _, insets ->
95+
val statusInsets = insets.getInsets(
96+
WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.displayCutout()
97+
)
98+
ViewCompat.setPaddingRelative(
99+
statusTop,
100+
initialTopStart,
101+
initialTopPadding + statusInsets.top,
102+
initialTopEnd,
103+
initialTopBottom
104+
)
105+
106+
val navAndGesturesInsets = insets.getInsets(
107+
WindowInsetsCompat.Type.navigationBars() or WindowInsetsCompat.Type.systemGestures()
108+
)
109+
val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime())
110+
val bottomInset = maxOf(navAndGesturesInsets.bottom, imeInsets.bottom)
111+
ViewCompat.setPaddingRelative(
112+
statusBottom,
113+
initialBottomStart,
114+
initialBottomTop,
115+
initialBottomEnd,
116+
initialBottomPadding + bottomInset
117+
)
118+
119+
insets
120+
}
121+
122+
fragmentBinding.root.doOnAttach { ViewCompat.requestApplyInsets(it) }
80123
}
81124

82125

@@ -96,9 +139,11 @@ class CameraMLKitFragment(cameraMLKitCallback: CameraMLKitCallback) : CameraFrag
96139
}
97140

98141
override fun onDestroyView() {
142+
binding?.root?.let { ViewCompat.setOnApplyWindowInsetsListener(it, null) }
99143
if (!disposable.isDisposed()) {
100144
disposable.dispose();
101145
}
146+
binding = null
102147
super.onDestroyView()
103148
// customView.onDestroy()
104149
}

app/android/app/src/main/java/com/proofofpassportapp/ui/QrCodeScannerFragment.kt

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ import android.graphics.Bitmap
2727
import android.os.Bundle
2828
import android.os.Handler
2929
import android.os.Looper
30-
import android.util.Log
3130
import android.view.LayoutInflater
3231
import android.view.View
3332
import android.view.ViewGroup
3433
import android.widget.Toast
34+
import androidx.core.view.ViewCompat
35+
import androidx.core.view.WindowInsetsCompat
36+
import androidx.core.view.doOnAttach
3537
import com.proofofpassportapp.utils.QrCodeDetectorProcessor
3638
import example.jllarraz.com.passportreader.R
3739
import example.jllarraz.com.passportreader.databinding.FragmentCameraMrzBinding
@@ -64,6 +66,47 @@ class QrCodeScannerFragment(callback: QRCodeScannerCallback) : CameraFragment()
6466

6567
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
6668
super.onViewCreated(view, savedInstanceState)
69+
val fragmentBinding = binding ?: return
70+
val statusTop = fragmentBinding.statusViewTop
71+
val statusBottom = fragmentBinding.statusViewBottom
72+
val initialTopStart = ViewCompat.getPaddingStart(statusTop)
73+
val initialTopPadding = statusTop.paddingTop
74+
val initialTopEnd = ViewCompat.getPaddingEnd(statusTop)
75+
val initialTopBottom = statusTop.paddingBottom
76+
val initialBottomStart = ViewCompat.getPaddingStart(statusBottom)
77+
val initialBottomTop = statusBottom.paddingTop
78+
val initialBottomEnd = ViewCompat.getPaddingEnd(statusBottom)
79+
val initialBottomPadding = statusBottom.paddingBottom
80+
81+
ViewCompat.setOnApplyWindowInsetsListener(fragmentBinding.root) { _, insets ->
82+
val statusInsets = insets.getInsets(
83+
WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.displayCutout()
84+
)
85+
ViewCompat.setPaddingRelative(
86+
statusTop,
87+
initialTopStart,
88+
initialTopPadding + statusInsets.top,
89+
initialTopEnd,
90+
initialTopBottom
91+
)
92+
93+
val navAndGesturesInsets = insets.getInsets(
94+
WindowInsetsCompat.Type.navigationBars() or WindowInsetsCompat.Type.systemGestures()
95+
)
96+
val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime())
97+
val bottomInset = maxOf(navAndGesturesInsets.bottom, imeInsets.bottom)
98+
ViewCompat.setPaddingRelative(
99+
statusBottom,
100+
initialBottomStart,
101+
initialBottomTop,
102+
initialBottomEnd,
103+
initialBottomPadding + bottomInset
104+
)
105+
106+
insets
107+
}
108+
109+
fragmentBinding.root.doOnAttach { ViewCompat.requestApplyInsets(it) }
67110
}
68111

69112

@@ -83,9 +126,11 @@ class QrCodeScannerFragment(callback: QRCodeScannerCallback) : CameraFragment()
83126
}
84127

85128
override fun onDestroyView() {
129+
binding?.root?.let { ViewCompat.setOnApplyWindowInsetsListener(it, null) }
86130
if (!disposable.isDisposed) {
87131
disposable.dispose();
88132
}
133+
binding = null
89134
super.onDestroyView()
90135
}
91136

packages/mobile-sdk-alpha/android/src/main/java/com/selfxyz/selfSDK/ui/CameraMLKitFragment.kt

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ import android.graphics.Color
2828
import android.os.Bundle
2929
import android.os.Handler
3030
import android.os.Looper
31-
import android.util.Log
3231
import android.view.LayoutInflater
3332
import android.view.View
3433
import android.view.ViewGroup
3534
import android.widget.Toast
35+
import androidx.core.view.ViewCompat
36+
import androidx.core.view.WindowInsetsCompat
37+
import androidx.core.view.doOnAttach
3638
import com.google.mlkit.vision.text.Text
3739

3840

@@ -77,6 +79,47 @@ class CameraMLKitFragment(cameraMLKitCallback: CameraMLKitCallback) : CameraFrag
7779

7880
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
7981
super.onViewCreated(view, savedInstanceState)
82+
val fragmentBinding = binding ?: return
83+
val statusTop = fragmentBinding.statusViewTop
84+
val statusBottom = fragmentBinding.statusViewBottom
85+
val initialTopStart = ViewCompat.getPaddingStart(statusTop)
86+
val initialTopPadding = statusTop.paddingTop
87+
val initialTopEnd = ViewCompat.getPaddingEnd(statusTop)
88+
val initialTopBottom = statusTop.paddingBottom
89+
val initialBottomStart = ViewCompat.getPaddingStart(statusBottom)
90+
val initialBottomTop = statusBottom.paddingTop
91+
val initialBottomEnd = ViewCompat.getPaddingEnd(statusBottom)
92+
val initialBottomPadding = statusBottom.paddingBottom
93+
94+
ViewCompat.setOnApplyWindowInsetsListener(fragmentBinding.root) { _, insets ->
95+
val statusInsets = insets.getInsets(
96+
WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.displayCutout()
97+
)
98+
ViewCompat.setPaddingRelative(
99+
statusTop,
100+
initialTopStart,
101+
initialTopPadding + statusInsets.top,
102+
initialTopEnd,
103+
initialTopBottom
104+
)
105+
106+
val navAndGesturesInsets = insets.getInsets(
107+
WindowInsetsCompat.Type.navigationBars() or WindowInsetsCompat.Type.systemGestures()
108+
)
109+
val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime())
110+
val bottomInset = maxOf(navAndGesturesInsets.bottom, imeInsets.bottom)
111+
ViewCompat.setPaddingRelative(
112+
statusBottom,
113+
initialBottomStart,
114+
initialBottomTop,
115+
initialBottomEnd,
116+
initialBottomPadding + bottomInset
117+
)
118+
119+
insets
120+
}
121+
122+
fragmentBinding.root.doOnAttach { ViewCompat.requestApplyInsets(it) }
80123
}
81124

82125

@@ -96,9 +139,11 @@ class CameraMLKitFragment(cameraMLKitCallback: CameraMLKitCallback) : CameraFrag
96139
}
97140

98141
override fun onDestroyView() {
142+
binding?.root?.let { ViewCompat.setOnApplyWindowInsetsListener(it, null) }
99143
if (!disposable.isDisposed()) {
100144
disposable.dispose();
101145
}
146+
binding = null
102147
super.onDestroyView()
103148
}
104149

packages/mobile-sdk-alpha/android/src/main/res/layout/fragment_camera_mrz.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<TextView android:id="@+id/status_view_top"
2828
android:layout_width="wrap_content"
2929
android:layout_height="wrap_content"
30-
android:layout_above="@+id/status_view_bottom"
30+
android:layout_alignParentTop="true"
3131
android:layout_margin="14dp"
3232
android:background="#0000"
3333
android:text=""

0 commit comments

Comments
 (0)