I am having problem that I am not able to open camera from webview in that I am having php page so I have to open gallery and camera from there but I am not able to do what I got from this link "https://gist.github.com/jhonsore/8a8378c147ec00ac6f3fa53569c82ef8". I can open gallery but not camera please give me any solution.
5 Answers
A working example in Kotlin for Android 7+
Add camera permissions
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CAMERA2" />
Configure your WebView
private fun configureWebViewSettings() {
binding.webView.settings.javaScriptEnabled = true
binding.webView.settings.domStorageEnabled = true
binding.webView.settings.setSupportZoom(false)
binding.webView.settings.allowFileAccess = true
binding.webView.settings.allowContentAccess = true
binding.webView.webChromeClient = getCustomWebChromeClient()
}
Add the lines below to your Activity
private var imagePathCallback: ValueCallback<Array<Uri>>? = null
private var cameraImagePath: String? = null
Implement a WebChromeClient
and add it to your WebView
private fun getCustomWebChromeClient() = object : WebChromeClient() {
override fun onShowFileChooser(
view: WebView?,
filePath: ValueCallback<Array<Uri>>?,
fileChooserParams: FileChooserParams?
): Boolean {
if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
requestPermissions(arrayOf(Manifest.permission.CAMERA), CAMERA_REQUEST_CODE)
imagePathCallback?.onReceiveValue(null)
imagePathCallback = null
imagePathCallback = filePath
val takePictureIntent = createImageCaptureIntent()
val contentSelectionIntent = Intent(Intent.ACTION_GET_CONTENT)
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE)
contentSelectionIntent.type = INTENT_FILE_TYPE
val intentArray: Array<Intent?>
intentArray = takePictureIntent?.let { arrayOf(it) } ?: arrayOfNulls(0)
val chooserIntent = Intent(Intent.ACTION_CHOOSER)
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent)
chooserIntent.putExtra(Intent.EXTRA_TITLE, getString(R.string.file_chooser_title))
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray)
try {
startActivityForResult(chooserIntent, REQUEST_SELECT_FILE)
} catch (e: ActivityNotFoundException) {
imagePathCallback = null
cameraImagePath = null
Toast.makeText(
this@MainActivity,
getString(R.string.cannot_open_file_chooser_txt),
Toast.LENGTH_LONG
).show()
return false
}
return true
}
private fun createImageCaptureIntent(): Intent? {
var captureImageIntent: Intent? = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (captureImageIntent?.resolveActivity(packageManager) != null) {
var imageFile: File? = null
try {
imageFile = createImageFile()
captureImageIntent.putExtra("CameraImagePath", cameraImagePath)
} catch (ex: IOException) {
ex.printStackTrace()
}
if (imageFile != null) {
cameraImagePath = CAMERA_PHOTO_PATH_POSTFIX + imageFile.absolutePath
captureImageIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile))
} else {
captureImageIntent = null
}
}
return captureImageIntent
}
private fun createImageFile(): File? {
val timeStamp = SimpleDateFormat.getDateInstance().format(Date())
val imageFileName = PHOTO_NAME_POSTFIX + timeStamp + "_"
val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(imageFileName, PHOTO_FORMAT, storageDir)
}
Implement onRequestPermissionsResult
in your Activity
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == CAMERA_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(
this,
getString(R.string.amera_permission_granted_txt),
Toast.LENGTH_LONG
).show()
} else {
Toast.makeText(
this,
getString(R.string.camera_permission_denied_txt),
Toast.LENGTH_LONG
).show()
}
}
}
Implement onActivityResult
in your Activity
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode != REQUEST_SELECT_FILE || imagePathCallback == null) return
var results: Array<Uri>? = null
if (resultCode == RESULT_OK) {
if (data == null) {
if (cameraImagePath != null) results = arrayOf(Uri.parse(cameraImagePath))
} else {
val dataString = data.dataString
if (dataString != null) results = arrayOf(Uri.parse(dataString))
}
}
imagePathCallback?.onReceiveValue(results)
imagePathCallback = null
}
Constants
companion object {
private const val CAMERA_REQUEST_CODE = 113
private const val REQUEST_SELECT_FILE = 13
private const val INTENT_FILE_TYPE = "image/*"
private const val CAMERA_PHOTO_PATH_POSTFIX = "file:"
private const val PHOTO_NAME_POSTFIX = "JPEG_"
private const val PHOTO_FORMAT = ".jpg"
}
Try and see, it should work.

- 5,149
- 16
- 63
- 104
Did you grant Camera permission into your WebView's WebChromeClient?
Please add camera permission into your AndroidManifest.xml.
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CAMERA2" />
Set WebChromeClient into your WebView.
webView.setWebChromeClient(new ChromeClient())
Define the your ChromeClient class.
public class ChromeClient extends WebChromeClient {
@Override
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
if (!hasPermissions(MainActivity.this, PERMISSIONS)) {
checkStoragePermission();
return false;
}
// Double check that we don't have any existing callbacks
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePath;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Select Photo");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, Constant.INPUT_FILE_REQUEST_CODE);
return true;
}
}
Here are variables.
String[] PERMISSIONS = {
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
Check the storage and camera permission.
private void checkStoragePermission() {
String permission = Manifest.permission.WRITE_EXTERNAL_STORAGE;
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, Constant.REQUEST_STORAGE_PERMISSION);
} else {
checkCameraPermission();
}
}
private void checkCameraPermission() {
String permission = Manifest.permission.CAMERA;
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, Constant.REQUEST_CAMERA_PERMISSION);
} else {
onPermissionGranted();
}
}
After that, I can access to camera and gallery.
Hope it to be helpful.

- 445
- 1
- 8
- 19
-
that works well for me but after that I'm not able to get the picture back from the camera! any help please? – issamabuaqlien Mar 28 '20 at 22:57
For Android 10, SDK 30
Add android:requestLegacyExternalStorage="true" in application tag in manifest
https://stackoverflow.com/a/65415381/7775500
this might help you ..

- 307
- 3
- 8
I also had this problem too. I will share it with others who are likely to have this problem in the future.
You must have the camera permission in the manifest and grant it in the onPermissionRequest
methode in your WebChromeClient
and be sure to set setMediaPlaybackRequiresUserGesture
to false in the webView setting.
Add this permission:
<uses-permission android:name="android.permission.CAMERA" />
Add this in webView setting:
binding.webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
And grant the permission in onPermissionRequest methode:
@Override
public void onPermissionRequest(final PermissionRequest request) {
final String[] requestedResources = request.getResources();
request.grant(requestedResources);
}
for more information see this link:

- 11
- 1
- 6
-
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/31119312) – Abhishek Dutt Feb 25 '22 at 05:41
Surely you need the permissions to open the camera on android.
Edit the manifest like this:
<uses-permission android:name="android.permission.CAMERA" />
You might also need a library not included

- 19
- 11