Skip to content

Android WebView: getUserMedia fails (missing onPermissionRequest + MODIFY_AUDIO_SETTINGS) #144

Description

@philippspeck

Summary

navigator.mediaDevices.getUserMedia() fails on Android even when the app has RECORD_AUDIO granted in system settings.

Two separate gaps in the stock Android WebView setup cause this:

  1. WebChromeClient.onPermissionRequest is not implemented — the WebView never grants RESOURCE_AUDIO_CAPTURE to web content, so getUserMedia() rejects with NotAllowedError: Permission denied.
  2. MODIFY_AUDIO_SETTINGS is missing from the merged manifest when RECORD_AUDIO is present — after fixing (1), Chromium logs Unable to select communication device! and getUserMedia() fails with NotReadableError: Could not start audio source (common when echoCancellation is requested or on recent WebView/Chromium builds).

Steps to reproduce

  1. Create a NativePHP Mobile app with microphone access (RECORD_AUDIO in the built manifest, e.g. via a plugin or manual manifest entry).
  2. Grant microphone permission in Android app settings.
  3. From JavaScript in the WebView, call:
await navigator.mediaDevices.getUserMedia({ audio: true });
  1. Observe console / logcat.

Expected behavior

Microphone capture starts; getUserMedia() resolves with a MediaStream.

Actual behavior

Without onPermissionRequest:

NotAllowedError: Permission denied

No onPermissionRequest callback is logged.

After adding onPermissionRequest manually (still without MODIFY_AUDIO_SETTINGS):

E chromium: [ERROR:media/audio/android/audio_manager_android.cc:876] Unable to select communication device!
NotReadableError: Could not start audio source

Environment

  • Device: Google Pixel 7, Android 16
  • WebView: Chrome 148 / Android System WebView 148
  • NativePHP Mobile: 3.x (nativephp/mobile ^3.3)
  • Reproduced with Livewire + Alpine.js voice recording via Web Audio API (getUserMedia + AudioWorkletNode)

Proposed fix

  1. Implement onPermissionRequest in WebViewManager.createWebChromeClient(), granting capture resources when the matching Android runtime permission is already held.
  2. When merging plugin manifest permissions, also inject android.permission.MODIFY_AUDIO_SETTINGS whenever android.permission.RECORD_AUDIO is present (Chromium needs this for WebView audio routing / communication device selection).

Happy to submit a PR if this approach looks good.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions