Tuesday, 9 June 2020

Android WebView: Handling Geolocation Permission Request

  1 comment
Image
In this tutorial we will geolocation permission in the app that load a website. So very first step is to add the required permission in the AndroidManifest.xml file

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:minHeight="4dp"
android:padding="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<WebView
android:id="@+id/webView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressBar" />
</androidx.constraintlayout.widget.ConstraintLayout>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
import android.Manifest
import android.annotation.SuppressLint
import android.content.DialogInterface
import android.content.pm.PackageManager
import android.net.http.SslError
import android.os.Bundle
import android.view.KeyEvent
import android.webkit.*
import android.widget.ProgressBar
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_web.*
class WebActivity : AppCompatActivity() {
var pageUrl: String = "https://couponia.co/"
var mGeoLocationRequestOrigin: String? = null
var mGeoLocationCallback: GeolocationPermissions.Callback? = null
val MAX_PROGRESS = 100
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_web)
initWebView()
setWebClient()
loadUrl(pageUrl)
}
@SuppressLint("SetJavaScriptEnabled")
private fun initWebView() {
webView.settings.javaScriptEnabled = true
webView.settings.loadWithOverviewMode = true
webView.settings.useWideViewPort = true
webView.settings.domStorageEnabled = true
webView.settings.databaseEnabled = true
webView.settings.setAppCacheEnabled(true)
webView.webViewClient = object : WebViewClient() {
override
fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) {
handler?.proceed()
}
}
}
private fun setWebClient() {
webView.webChromeClient = object : WebChromeClient() {
override fun onGeolocationPermissionsShowPrompt(
origin: String?,
callback: GeolocationPermissions.Callback?
) {
if (ContextCompat.checkSelfPermission(
this@WebActivity,
Manifest.permission.ACCESS_FINE_LOCATION
)
!= PackageManager.PERMISSION_GRANTED
) {
if (ActivityCompat.shouldShowRequestPermissionRationale(
this@WebActivity,
Manifest.permission.ACCESS_FINE_LOCATION
)
) {
AlertDialog.Builder(this@WebActivity)
.setMessage("Please turn ON the GPS to make app work smoothly")
.setNeutralButton(
android.R.string.ok,
DialogInterface.OnClickListener { dialogInterface, i ->
mGeoLocationCallback = callback
mGeoLocationRequestOrigin = origin
ActivityCompat.requestPermissions(
this@WebActivity,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 1001
)
})
.show()
} else {
//no explanation need we can request the locatio
mGeoLocationCallback = callback
mGeoLocationRequestOrigin = origin
ActivityCompat.requestPermissions(
this@WebActivity,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 1001
)
}
} else {
//tell the webview that permission has granted
callback!!.invoke(origin, true, true)
}
}
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
progressBar.progress = newProgress
if (newProgress < MAX_PROGRESS && progressBar.visibility == ProgressBar.GONE) {
progressBar.visibility = ProgressBar.VISIBLE
}
if (newProgress == MAX_PROGRESS) {
progressBar.visibility = ProgressBar.GONE
}
}
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
// Check if the key event was the Back button and if there's history
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
webView.goBack()
return true
}
// If it wasn't the Back key or there's no web page history, exit the activity)
return super.onKeyDown(keyCode, event)
}
private fun loadUrl(pageUrl: String) {
webView.loadUrl(pageUrl)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
1001 -> {
//if permission is cancel result array would be empty
if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//permission was granted
if (mGeoLocationCallback != null) {
mGeoLocationCallback!!.invoke(mGeoLocationRequestOrigin, true, true)
}
} else {
//permission denied
if (mGeoLocationCallback != null) {
mGeoLocationCallback!!.invoke(mGeoLocationRequestOrigin, false, false)
}
}
}
}
}
view raw WebActivity.kt hosted with ❤ by GitHub

1 comment :