Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use camera through Webview? #508

Closed
KamilGromov1122 opened this issue Apr 17, 2019 · 62 comments
Closed

How to use camera through Webview? #508

KamilGromov1122 opened this issue Apr 17, 2019 · 62 comments
Labels

Comments

@KamilGromov1122
Copy link

Hi.

I am a new React Native developer.
Now, I am implementing some function using React Native.

I want to use Camera and Mic through Webview.
My site works well on Mobile Browser, but when I call that url in Webview, I can't use Camera and Mic.

Please help me.

Thanks.

@KamilGromov1122
Copy link
Author

I can't find any proper answer for this question.

@Titozzz
Copy link
Collaborator

Titozzz commented Apr 20, 2019

#231 is maybe related?

@hartatovich
Copy link

hartatovich commented Apr 22, 2019

#231 is maybe related?

i'm also having the same issue...
tried to review #231 as well but didn't find a clear answer about how to solve that

"react-native-webview": "^5.7.0"

what i'm trying to do:

  <WebView
                useWebKit
                originWhitelist={['*']}
                allowsInlineMediaPlayback
                source={{uri: 'https://marcusbelcher.github.io/wasm-asm-camera-webgl-test/index.html'}}
            />

you can check the webview source url (its a fully tested url for the camera that works well on desktops and mobile as well.. however in the webview it seems not to work

AndroidManifest.xml

 <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

@Titozzz @KamilGromov1122 @Javascript-ninja

@mharis161
Copy link

@hartatovich did you find any solution yet?

@hartatovich
Copy link

@mharis161 not yet...
my guess we just need some one to merge a pull request from #231
but waiting for someone to reply :)

cc - @Titozzz

@mharis161
Copy link

@hartatovich i commited @Javascript-ninja's file 'RNCWebViewManager.java' to my code but got this error:

Task :react-native-webview:compileDebugJavaWithJavac FAILED
D:\Android\workspace\demoApp\node_modules\react-native-webview\android\src\main\java\com\reactnativecommunity\webview\RNCWebViewManager.java:157: error: incompatible types: String cannot be converted to WritableMap
dispatchEvent(view, new TopShouldStartLoadWithRequestEvent(view.getId(), url));
^
D:\Android\workspace\demoApp\node_modules\react-native-webview\android\src\main\java\com\reactnativecommunity\webview\RNCWebViewManager.java:165: error: incompatible types: String cannot be converted to WritableMap
dispatchEvent(view, new TopShouldStartLoadWithRequestEvent(view.getId(), request.getUrl().toString()));
^
D:\Android\workspace\demoApp\node_modules\react-native-webview\android\src\main\java\com\reactnativecommunity\webview\RNCWebViewManager.java:788: error: cannot find symbol
return this.aPackage.getModule();
^
symbol: method getModule()
location: variable aPackage of type RNCWebViewPackage
Note: D:\Android\workspace\demoApp\node_modules\react-native-webview\android\src\main\java\com\reactnativecommunity\webview\RNCWebViewManager.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: D:\Android\workspace\demoApp\node_modules\react-native-webview\android\src\main\java\com\reactnativecommunity\webview\RNCWebViewManager.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
3 errors

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':react-native-webview:compileDebugJavaWithJavac'.

Compilation failed; see the compiler error output for details.

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.1.1/userguide/command_line_interface.html#sec:command_line_warnings

@taimoorimran
Copy link

My current RN Version is : 0.59.6 and i am getting Permission Denied error for camera and mic too. Did you guys find any workaround yet?

@kirill578
Copy link

kirill578 commented May 8, 2019

You need to prompt the user to give you the camera permission. I believe that should be done by this library, must have been missed

@gwmccull
Copy link

I was able to confirm a workaround. I have two screens that use the camera: one is a React Native screen that uses react-native-image-picker and the other is a webview where you can take/upload a pic.

  1. If the user goes to the webview first, they cannot take or pick a photo.
  2. if the user goes to the React Native screen, accesses the image picker (which asks about permissions), and then goes to the webview, they are now able to take/pick a photo

I'm going to look into a work around where I just ask people for permission to use the camera when they open the webview

@gwmccull
Copy link

I confirmed that you can use a library like react-native-permissions to grant the necessary permissions when the webview is loaded. I'm just asking when the webview is mounted but I guess you could get tricky and watch the webview's URL to pop the permission dialog when the url is set to the page where you access the camera

@kirill578
Copy link

kirill578 commented Jun 13, 2019 via email

@westoncolemanl
Copy link

westoncolemanl commented Jun 27, 2019

My CAMERA and RECORD_AUDIO are both granted. But I am still unable to use my Camera over web view. Any thoughts on this?

06-27 15:28:26.010  7278  7379 I ReactNativeJS: { 'android.permission.RECORD_AUDIO': 'granted',
06-27 15:28:26.010  7278  7379 I ReactNativeJS:   'android.permission.CAMERA': 'granted' }

I am using the web view URI given above to test.
https://marcusbelcher.github.io/wasm-asm-camera-webgl-test/index.html

The error I receive is

Camera: Failed, an error occurred and did not inject camera feed into the webpage.

Error: { "name": "NotAllowedError", "message": Permission denied" }

This error may appear if you have not clicked a permissions pop up (Browser dependent), manually blocked the camera, or if the experience is being served from an unsecured host. If the HTTPS test failed please click "Force redirect to HTTPS" and try again.

@barbodco
Copy link

barbodco commented Sep 1, 2019

My CAMERA and RECORD_AUDIO are both granted. But I am still unable to use my Camera over web view. Any thoughts on this?

06-27 15:28:26.010  7278  7379 I ReactNativeJS: { 'android.permission.RECORD_AUDIO': 'granted',
06-27 15:28:26.010  7278  7379 I ReactNativeJS:   'android.permission.CAMERA': 'granted' }

I am using the web view URI given above to test.
https://marcusbelcher.github.io/wasm-asm-camera-webgl-test/index.html

The error I receive is

Camera: Failed, an error occurred and did not inject camera feed into the webpage.

Error: { "name": "NotAllowedError", "message": Permission denied" }

This error may appear if you have not clicked a permissions pop up (Browser dependent), manually blocked the camera, or if the experience is being served from an unsecured host. If the HTTPS test failed please click "Force redirect to HTTPS" and try again.

did you find any solution yet

@el-psy-k
Copy link

el-psy-k commented Sep 4, 2019

#719 This PR is included in version 6.6.0

@lfalkner
Copy link

lfalkner commented Sep 13, 2019

I am still seeing the same issue as above, using the latest version of the webview. as commented on this issue, I'd be happy to bring in changes from this library to address permissions issues, as well as to avoid assuming 'accept' headers

@davidbongcc
Copy link

Hi.

I am a new React Native developer.
Now, I am implementing some function using React Native.

I want to use Camera and Mic through Webview.
My site works well on Mobile Browser, but when I call that url in Webview, I can't use Camera and Mic.

Please help me.

Thanks.

Did you manage to get the solution?

@DevelopersTopHat
Copy link

I was trying to solve a similar problem to this. In order to see my camera on my website through my webview I had to request permission for CAMERA, and RECORD_AUDIO. Enabling these through my react-native app allowed me to see my camera, but I also had an incoming camera feed (third party camera) that wasn't showing up. In order to fix it, I add the mediaPlaybackRequiresUserAction={false} prop to allow the other camera feed to be seen through the webview. This solved my issue, and it might solve yours as well.

@gizioo
Copy link

gizioo commented Nov 13, 2019

I also experienced an issue where Android would only launch a file browser and did not let the user choose the camera.

For anyone who is trying to do a simple upload from a html input, remember to add accept="image/*" attribute.

<input type="file" name="pic" accept="image/*">

@TchernyavskyDaniil
Copy link

any solutions?

@ZeeshanAhmadKhalil
Copy link

I am also facing the same problem in react-native-webview. But I am getting the same problem if I open the link directly on the android chrome. For PC chrome there is no issue.

@kchens
Copy link

kchens commented Jan 9, 2020

Hi @gwmccull ! I'm running into this issue with Android. Do you remember if this was a workaround for the Android build? Or was it for both?

@gwmccull
Copy link

hi @kchens! We're doing the same thing for iOS & Android but the names of the permissions appear to be different. It looks like there's been work on this since I first found that solution but I haven't tried to reevaluating it. It's still working for us though

@kchens
Copy link

kchens commented Jan 14, 2020

@gwmccull what Android version and React-Native versions is your company's app on right now?

@gwmccull
Copy link

@kchens we're using RN 0.61.5 and we're supporting Android 9+. We're looking into expanding back to Android 8+ (we supported it up until a few months ago) and I'm not expecting this to be an issue

@cosecantt
Copy link

cosecantt commented Feb 3, 2020

I have the same issue. Camera does not work in webview when standalone Android app is built with expo. But it works through the expo client with the same configuration. Any solution?

@Gjoshi3107
Copy link

actually i was getting the same issue for both camera and gallery
i asked the permissions at the url link and it worked.
(Of course your website needs to have the code to access the camera and gallery.)

var enteronce = false;

...

onNavigationStateChange(webView) {
    if (enteronce == false && webView.url.includes("PAGE LINK WHERE YOU OPEN CAMERA AND GALLERY")) {
        enteronce = true;         
        // enteronce is to enter inside the code and ask permissions only once or else the page will continue to ask permission
        
        this.requestCameraAndGalleryPermission();
    }
    else{
        enteronve=false;
    }
}
async requestCameraAndGalleryPermission() {
    try {
        var permission = await PermissionsAndroid.check(
            PermissionsAndroid.PERMISSIONS.CAMERA && PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE
        );
        console.log("camera && gallery permission granted:- ", permission);
        if (!permission) {
            const granted = await PermissionsAndroid.request(
                PermissionsAndroid.PERMISSIONS.CAMERA && PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE
            );
            if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                console.log('Camera && Gallery permissions granted');
            } else {
                console.log('Camera && Gallery permission denied');
            }
        }
    } catch (err) {
        console.warn(err);
    }
}

I hope this helps you as well.

@charkcl
Copy link

charkcl commented Apr 17, 2020

@Gjoshi3107 Thanks for your tips! Did you only try Android? Just wondering if iOS works?

@FadiAboMsalam
Copy link

any fix, update on this espacially on iOS ?

@vasanthhr
Copy link

vasanthhr commented May 20, 2020

Hello ,
Does reactnative webview supports to open camera for Iphone(IOS) ?

I tried using below code and working properly on Android phones and displaying live video.
In IPhone(IOS), I could see pop coming to open webcamera and white screen displays after clicking "Yes" permission to camera.

  async componentDidMount() {
   const { status } = await Permissions.askAsync(Permissions.CAMERA);
   const { status_camera_roll } = await Permissions.askAsync(Permissions.CAMERA_ROLL);

   this.setState({
     hasCameraPermission: status === 'granted'
   });
   
   }


  render() {
    const url = 'https://webcamtests.com/';
    return (
      <WebView
    useWebKit
      originWhitelist={['*']}
      allowsInlineMediaPlayback
    bounces={true}
        source={{
          uri: url,
        }}
        startInLoadingState
        scalesPageToFit
        javaScriptEnabledAndroid={true}
        javaScriptEnabled={true}        
        style={{ flex: 1 }}
      />
    );
  }

Please guide me . Thanks.

@github-actions github-actions bot added the Stale label Dec 1, 2020
@github-actions github-actions bot closed this as completed Dec 8, 2020
@shahidcodes
Copy link

Tried everything but still failing for android, iOS works fine.

Snack URL https://snack.expo.io/@shahidcodes/webview-get-user-media-test-android

@Zain228
Copy link

Zain228 commented May 6, 2021

Tried everything but still failing for android, iOS works fine.

Snack URL https://snack.expo.io/@shahidcodes/webview-get-user-media-test-android

Its working fine on Android but not on iOS

@shahidcodes
Copy link

@Zain228 not sure how you tested it, did you use the snack or cloned locally?
Which device? My android devices throw permission denied error when getUserMedia is called.

@Zain228
Copy link

Zain228 commented May 6, 2021

@Zain228 not sure how you tested it, did you use the snack or cloned locally?
Which device? My android devices throw permission denied error when getUserMedia is called.

I use my own iPhone for testing but its not working however on my Samsung phone its working fine

@wahaj-47
Copy link

wahaj-47 commented May 6, 2021

Tried everything but still failing for android, iOS works fine.

Snack URL https://snack.expo.io/@shahidcodes/webview-get-user-media-test-android

On Android add the prop

mediaPlaybackRequiresUserAction={false}

@wahaj-47
Copy link

wahaj-47 commented May 6, 2021

@Zain228 not sure how you tested it, did you use the snack or cloned locally?
Which device? My android devices throw permission denied error when getUserMedia is called.

I use my own iPhone for testing but its not working however on my Samsung phone its working fine

What iOS version are you running?

@shahidcodes
Copy link

shahidcodes commented May 6, 2021

@wahaj-47


mediaPlaybackRequiresUserAction={false}

That Is already set in the props still no luck.

https://snack.expo.io/@shahidcodes/webview-get-user-media-test-android

@wahaj-47
Copy link

wahaj-47 commented May 6, 2021

@wahaj-47


mediaPlaybackRequiresUserAction={false}

That Is already set in the props still no luck.

https://snack.expo.io/@shahidcodes/webview-get-user-media-test-android

Try adding

allowInlineMediaPlayback

These two props fixed the issue for me.

@Zain228
Copy link

Zain228 commented May 7, 2021

@Zain228 not sure how you tested it, did you use the snack or cloned locally?
Which device? My android devices throw permission denied error when getUserMedia is called.

I use my own iPhone for testing but its not working however on my Samsung phone its working fine

What iOS version are you running?

iOS 12!
is it working on latest iOS?

@wahaj-47
Copy link

wahaj-47 commented May 7, 2021

@Zain228 not sure how you tested it, did you use the snack or cloned locally?
Which device? My android devices throw permission denied error when getUserMedia is called.

I use my own iPhone for testing but its not working however on my Samsung phone its working fine

What iOS version are you running?

iOS 12!
is it working on latest iOS?

Yeah, works on iOS 14.

@princ09
Copy link

princ09 commented May 11, 2021

@wahaj-47 is it possible for you to share code or steps. I have added both props , still not working.

@Zain228
Copy link

Zain228 commented May 20, 2021

This works on both Android 10+ and iOS 14+
<WebView onLoadStart={()=>{console.log("Start")}} onLoadEnd={()=>setShouldShow(false)} userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36" source={{ uri: 'Your Website URL' }} originWhitelist={['*']} allowsInlineMediaPlayback javaScriptEnabled scalesPageToFit allowInlineMediaPlayback={true} mediaPlaybackRequiresUserAction={false} startInLoadingState onNavigationStateChange={(val)=>{ // Do Something on Page Change }} javaScriptEnabledAndroid geolocationEnabled={true} useWebkit />

@anhvoduy
Copy link

anhvoduy commented Jun 16, 2021

hi Zain228, it does not work as your WebView properties
Screen Shot 2021-06-17 at 12 35 08 AM

@devinsg
Copy link

devinsg commented Jun 17, 2021

web-view version 11.4.4: it does not work on IOS, why close this issue ?

@anhvoduy
Copy link

image

Finally, it works on my app with simple code like this, and verify IOS version on Iphone >= 14.6

@pjc0247
Copy link

pjc0247 commented Aug 17, 2021

this issue is still active on Android.

https://snack.expo.dev/UY4OhRSm5
image

(same on real devices)

@pjc0247
Copy link

pjc0247 commented Aug 19, 2021

I was able to solve this by adding <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /. lol

@geiz
Copy link

geiz commented Nov 9, 2021

I was able to solve this by adding <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /. lol

This works on both Android 10+ and iOS 14+ <WebView onLoadStart={()=>{console.log("Start")}} onLoadEnd={()=>setShouldShow(false)} userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36" source={{ uri: 'Your Website URL' }} originWhitelist={['*']} allowsInlineMediaPlayback javaScriptEnabled scalesPageToFit allowInlineMediaPlayback={true} mediaPlaybackRequiresUserAction={false} startInLoadingState onNavigationStateChange={(val)=>{ // Do Something on Page Change }} javaScriptEnabledAndroid geolocationEnabled={true} useWebkit />

Applied both of these and it worked. the MODIFY_AUDIO_SETTINGS was not intuitive.

Anyways, my permissions in AndroidManifest.xml and webview looked like this after

  <uses-permission android:name="android.permission.VIBRATE" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
  <uses-permission android:name="android.permission.MICROPHONE" />
  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />



 <WebView
    allowsInlineMediaPlayback={true}
    cacheEnabled={true}
    geolocationEnabled={false}
    javaScriptEnabled
    javaScriptEnabledAndroid={true}
    mediaPlaybackRequiresUserAction={false}
    mixedContentMode={'compatibility'}]
    originWhitelist={['*']}
    scalesPageToFit
    source={{uri: 'my url'}}
    startInLoadingState={true}
    useWebkit
    userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36"
  />

@djibarian
Copy link

I'm facing a slightly different problem (in iOS). When running the app for the first time the modal for asking permission pops up fine, showing the message in NSCameraUsageDescription in info.plist.

But I'd like to check that message in different languages.

Unfortunately, going to the app settings and revoking access to the camera ends up with the app opening the camera app but with a blank background (no image from the camera and a non-working trigger button).

So there's no way after the first modal to show it again (you give access and everything is fine; or you don't and get the blank camera; but not a new modal request nor a permission error).

@sopu0000
Copy link

sopu0000 commented Feb 4, 2022

My current RN Version is : 0.59.6 and i am getting Permission Denied error for camera and mic too. Did you guys find any workaround yet?

Did Any one find the solution please help?

@adrienfloor
Copy link

Hey guys

Slightly different problem here but I was hoping someone might have an answer. I've been searching the topic for 2 days and didn't get my answer.

I'm picking a video file from the library with the lib react-native-image-picker and I'd like to pass the video file to my webview. I need a JS file format in the webview, like it would be if it was coming from a basic element. The path I get from the picker to the video in the RN app looks like this : file:///var/mobile/Containers/Data/Application/7C0.....my_video.mov

Would anybody have a tip on the correct way to handle this ? It would be so so so much appreciated !

Thank you very much in advance 😌

@oviniciusfeitosa
Copy link

@anirudh711
Copy link

Hey,
If you are using expo to manage the project. You have to take a two fold approach:
In app.json add the following:

"permissions": [
"android.permission.MODIFY_AUDIO_SETTINGS"
]

Before you call your web view component, conditionally render it with permission like below with expo-camera

import React, { useEffect, useState } from "react";
import WebViewCustom from "../";
import { Camera, CameraType } from "expo-camera";
import { Text, View } from "react-native";
const [hasPermission, setHasPermission] = useState(null);
  useEffect(() => {
    (async () => {
      const { status } = await Camera.requestCameraPermissionsAsync();
      setHasPermission(status === "granted");
    })();
  }, []);
  if (hasPermission === null) {
    return <View />;
  }
  if (hasPermission === false) {
    return <Text>No access to camera</Text>;
  }
  if (hasPermission) {
    return <WebViewCustom uri={uri} />;
  }

@jhonpedro
Copy link

Thank you @anirudh711. This aproach worked overhere!

@EliotRaven
Copy link

EliotRaven commented Sep 21, 2022

use expo all worked few weeks ago, now have problem with mic and camera
camera not working and mic too

@ghashi
Copy link

ghashi commented Oct 21, 2022

the whereby site has some relevant information regarding this topic:

https://docs.whereby.com/embedding-rooms/in-a-mobile-app/in-react-native

  1. add permissions code:

you will need to add the corresponding permissions to be able to access both the camera and microphone as described in the Android and iOS sections.

  1. add some Webview props:
    <WebView
        startInLoadingState
        source={{ uri }}
        mediaPlaybackRequiresUserAction={false}

        // iOS specific:
        allowsInlineMediaPlayback

        // Android specific:
        javaScriptEnabled
        domStorageEnabled
    />
  1. Obs for iOS

On the iOS instructions, it recommends the following for iOS 14.2 and earlier:

Redirect to a browser (Safari by default) for iOS versions lower than 14.3:

@viniciosComerciante
Copy link

mediaPlaybackRequiresUserAction={false}

thank you very much, you saved my life

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests