Search code examples
androidwebviewphotoangular10

How to take photo or select gallery files in android webview


I have a component in angular with the functionality to take picture or select file

enter image description here

The file upload works fine, the problem is that it does not let me take photos, I already tried to adapt the code in various ways but it does not work.

How could I make that adjustment so that both options work, how could I identify which option was selected (take photo, select file)?

Angular code

Html

<input
    #inputFile
    accept="image/*,application/pdf"
    type="file"
    (change)="loadFile($event)"
    style="display: none;"
    onclick="this.value = null"
/>
<input
    #cameraFile
    accept="image/*"
    capture="camera"
    type="file"
    (change)="loadFile($event)"
    style="display: none;"
    onclick="this.value = null"
/>

Ts

selectOption(opcion: any) {
    if (opcion.tipoArchivo === this.documentType.documento.idDocumento) {
        switch (opcion.opcion) {
            case MenuBottomSheet.ELEGIR_FOTO:
                this.fileChooser.nativeElement.click();
                break;
            case MenuBottomSheet.TOMAR_FOTO:
                this.cameraFile.nativeElement.click();
                break;
        }
    }
}

Código android

web_view?.webChromeClient = object: WebChromeClient() {
    override fun onShowFileChooser(webView: WebView?, filePathCallback: ValueCallback<Array<Uri>>?,
        fileChooserParams: FileChooserParams): Boolean {
        Log.d("onShowFileChooser ======> ", "")
        super.onShowFileChooser(webView, filePathCallback, fileChooserParams)
        if (uploadMessage != null) {
            uploadMessage?.onReceiveValue(null)
            uploadMessage = null
        }
        uploadMessage = filePathCallback
        val intent: Intent = fileChooserParams.createIntent()
        try {
            startActivityForResult(intent, REQUEST_SELECT_FILE)
        } catch (e: ActivityNotFoundException) {
            uploadMessage = null
            return false
        }
        return true
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == RESULT_OK && (requestCode == REQUEST_SELECT_FILE || requestCode == REQUEST_IMAGE_CAPTURE)) {
        if (uploadMessage == null) {
            return
        }
        uploadMessage?.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data))
        uploadMessage = null
    }
}

Solution

  • I put here the code that worked for me

    override fun onShowFileChooser(webView: WebView?, filePathCallback: ValueCallback<Array<Uri>>?, fileChooserParams: FileChooserParams): Boolean {
        super.onShowFileChooser(webView, filePathCallback, fileChooserParams)
        if (uploadMessage != null) {
            uploadMessage?.onReceiveValue(null)
            uploadMessage = null
        }
        uploadMessage = filePathCallback
        if (fileChooserParams.isCaptureEnabled()) {
            takingPhoto = true
            var permissions = ArrayList<String>()
            if(!existCameraPermission()) {
                permissions.add(Manifest.permission.CAMERA);
            }
            if(!existMemoryWritePermission()) {
                permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            }
            if(!permissions.isEmpty()) {
                requestPermissions(permissions.toTypedArray(), 1);
            } else {
                takePhoto()
            }
        } else {
            takingPhoto = false
            val intent: Intent = fileChooserParams.createIntent()
            try {
                startActivityForResult(intent, REQUEST_SELECT_FILE)
            } catch (e: ActivityNotFoundException) {
                uploadMessage = null
                return false
            }
        }
        return true
    }
    
    
    
    fun takePhoto() {
        var takePictureIntent: Intent? = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        if (takePictureIntent?.resolveActivity(packageManager) != null) {
            var photoFile: File? = null
            try {
                photoFile = createImageFile()
            } catch (ex: IOException) {
                Log.d("ocurrio un error ================> ", ex.toString())
            }
            if (photoFile != null) {
                photoFileTmp = photoFile
                val uri = FileProvider.getUriForFile(activity, fileProvider, photoFile);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
            }
            startActivityForResult(takePictureIntent, REQUEST_SELECT_FILE)
        }
    }