Android
This document provides instructions to create a WebView into an Android project.
Android Manifest
Add these lines to the AndroidManifest.xml file in your app module:
<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)
This is an example of an activity using a WebView
class WebViewActivity : AppCompatActivity() {
private var filePathCallback: ValueCallback<Array<Uri>>? = null
private var isFilePickerShown = false
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)
}
/**
* The permission request is made when the activity is resumed.
* The webView is loaded only if the permission is granted.
*/
override fun onResume() {
super.onResume()
if (!isFilePickerShown) {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE
),
CAMERA_REQUEST_CODE
)
} else {
webView.loadUrl(url)
}
}
isFilePickerShown = false
}
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
}
/**
* The permission request result is handled here.
* If the permission is granted, the webView is loaded.
*/
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) {
webView.loadUrl(url)
}
}
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) {
request.grant(request.resources)
}
/**
* Callback will tell the host application that the current page would
* like to show a custom View in a particular orientation
*/
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)
)
// This will ensure the custom view is in fullscreen mode
window.decorView.systemUiVisibility = 3846 or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}
/**
* Callback will tell the host application that the current page exited full screen mode,
* and the app has to hide custom view.
*/
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
isFilePickerShown = true
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
}
}
Last updated