For the complete documentation index, see llms.txt. This page is also available as Markdown.

Android

Este documento fornece instruções para criar um WebView em um projeto Android.

Manifesto do Android

Adicione estas linhas ao arquivo AndroidManifest.xml no módulo do seu app:

<uses-feature
    android:name="android.hardware.camera"
    android:required="true" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Android WebView (Kotlin)

Este é um exemplo de uma activity usando uma WebView

class WebViewActivity : AppCompatActivity() {
    private var filePathCallback: ValueCallback<Array<Uri>>? = null
    private var permissionRequest: PermissionRequest? = null
    private lateinit var webView: WebView

    private val url = "https://cadastro.io/:token"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        this.webView = getWebView()
        setContentView(webView)
        webView.loadUrl(url)
    }

    private fun getWebView(): WebView {
        val webView = WebView(this)
        val webSettings = webView.settings
        webSettings.javaScriptEnabled = true
        webSettings.domStorageEnabled = true
        webSettings.mediaPlaybackRequiresUserGesture = false
        webSettings.javaScriptCanOpenWindowsAutomatically = true
        webSettings.loadWithOverviewMode = true
        webSettings.useWideViewPort = true
        webSettings.allowFileAccess = true
        webSettings.allowContentAccess = true
        webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
        webView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
        webView.webChromeClient = MyWebChromeClient()
        webView.webViewClient = WebViewClient()
        return webView
    }

    /**
     * O resultado da solicitação de permissão é tratado aqui.
     * Se a permissão for concedida, a webView é carregada.
     */
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String?>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == CAMERA_REQUEST_CODE && grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            permissionRequest?.grant(permissionRequest?.resources)
        } else {
            permissionRequest?.deny()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == FILE_CHOOSER_REQUEST_CODE) {
            if (filePathCallback == null) {
                return
            }
            val results = WebChromeClient.FileChooserParams.parseResult(resultCode, data)
            filePathCallback!!.onReceiveValue(results)
            filePathCallback = null
        }
    }

    private inner class MyWebChromeClient : WebChromeClient() {
        var originalOrientation: Int = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
        var originalVisibility: Int = View.INVISIBLE
        private var customView: View? = null
        private var customViewCallback: CustomViewCallback? = null

        override fun onPermissionRequest(request: PermissionRequest) {
            val requestedAndroidPermissions = ArrayList<String>()
            for (requestedResource in request.resources) {
                if (requestedResource == PermissionRequest.RESOURCE_VIDEO_CAPTURE &&
                    ContextCompat.checkSelfPermission(
                        this@WebViewActivity.applicationContext,
                        Manifest.permission.CAMERA
                    ) != PackageManager.PERMISSION_GRANTED) {
                    requestedAndroidPermissions.add(Manifest.permission.CAMERA)
                }
            }
            if (requestedAndroidPermissions.isEmpty()) {
                request.grant(request.resources)
                return
            }
            permissionRequest = request
            requestPermissions(
                requestedAndroidPermissions.toTypedArray<String>(),
                CAMERA_REQUEST_CODE
            )
        }

        /**
         * O callback informará ao aplicativo host que a página atual desejaria
         * exibir uma View personalizada em uma orientação específica
         */
        override fun onShowCustomView(view: View, callback: CustomViewCallback) {
            if (customView != null) {
                onHideCustomView()
                return
            }
            customView = view
            originalVisibility = window.decorView.systemUiVisibility
            originalOrientation = requestedOrientation
            (window.decorView as FrameLayout).addView(
                customView,
                FrameLayout.LayoutParams(-1, -1)
            )
            // Isso garantirá que a view personalizada esteja em modo de tela cheia
            window.decorView.systemUiVisibility = 3846 or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        }

        /**
         * O callback informará ao aplicativo host que a página atual saiu do modo de tela cheia,
         * e o app precisa ocultar a view personalizada.
         */
        override fun onHideCustomView() {
            (window.decorView as FrameLayout).removeView(customView)
            customView = null
            window.decorView.systemUiVisibility = originalVisibility
            requestedOrientation = originalOrientation
            if (customViewCallback != null) {
                customViewCallback!!.onCustomViewHidden()
            }
            customViewCallback = null
        }

        override fun onShowFileChooser(
            webView: WebView,
            filePathCallback: ValueCallback<Array<Uri>>,
            fileChooserParams: FileChooserParams
        ): Boolean {
            if (this@WebViewActivity.filePathCallback != null) {
                this@WebViewActivity.filePathCallback?.onReceiveValue(null)
            }
            this@WebViewActivity.filePathCallback = filePathCallback

            val intent = fileChooserParams.createIntent()
            try {
                startActivityForResult(intent, FILE_CHOOSER_REQUEST_CODE)
            } catch (e: ActivityNotFoundException) {
                this@WebViewActivity.filePathCallback = null
                return false
            }
            return true
        }
    }

    companion object {
        private const val CAMERA_REQUEST_CODE = 1001
        private const val FILE_CHOOSER_REQUEST_CODE = 1002
    }
}

Android WebView (Java)

Atualizado