diff --git a/README.md b/README.md
index 3e71ebe7..509a5166 100644
--- a/README.md
+++ b/README.md
@@ -468,6 +468,16 @@ The `retryPredicate` is part of `HCaptchaConfig` that may get persist during app
So pay attention to this aspect and make sure that `retryPredicate` is serializable to avoid
`android.os.BadParcelableException` in run-time.
+### Camera Permission
+
+Challenges that use the camera require the host app to declare and request the `CAMERA` permission at runtime (Android 6.0+):
+
+```xml
+
+```
+
+Requires Android 5.0+ (API 21).
+
### User Journeys (Enterprise)
You can optionally enable user journeys to send recent interaction events alongside your verification request.
diff --git a/example-app/src/main/AndroidManifest.xml b/example-app/src/main/AndroidManifest.xml
index eb1f08ab..63dc7cba 100644
--- a/example-app/src/main/AndroidManifest.xml
+++ b/example-app/src/main/AndroidManifest.xml
@@ -1,6 +1,11 @@
+
+
+
+
+
+
= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ // Allow media playback to start without a user gesture.
+ settings.setMediaPlaybackRequiresUserGesture(false);
+ }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webView.setWebViewClient(new HCaptchaWebClient(handler));
}
@@ -260,5 +265,29 @@ public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
public void onProgressChanged(WebView view, int newProgress) {
HCaptchaLog.d("[webview] onProgressChanged %d%%", newProgress);
}
+
+ @Override
+ @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+ public void onPermissionRequest(final PermissionRequest request) {
+ // Grant only the requested capture resource; audio is never requested, which
+ // avoids forcing host apps to declare RECORD_AUDIO.
+ boolean wantsCapture = false;
+ for (final String resource : request.getResources()) {
+ if (PermissionRequest.RESOURCE_VIDEO_CAPTURE.equals(resource)) {
+ wantsCapture = true;
+ break;
+ }
+ }
+ if (wantsCapture) {
+ // The requested surface only composites on a hardware layer; the default
+ // software layer (disableHardwareAcceleration) would render it blank.
+ webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ request.grant(new String[]{PermissionRequest.RESOURCE_VIDEO_CAPTURE});
+ HCaptchaLog.d("[webview] onPermissionRequest granted");
+ } else {
+ request.deny();
+ HCaptchaLog.d("[webview] onPermissionRequest denied");
+ }
+ }
}
}