0

I am trying to make an Android App that just shows a map inside a WebView component.

I have started with the How to Convert a Website into an Android Application using Android Studio tutorial and then try to allow the browser to use JavaScript and the position of the device.

To allow the WebView to use the position I have applied the following guides and answers

but, when I click on the current position button, I still get the following message:

Geolocation error: Application does not have sufficient geolocation permissions..

Error message screen

I don't think this is a duplicate question as this is specific about Leafet map JS library and about a specific case.

What I have tried

At the moment my app is made of the following files:

MainActivity.java

package com.vinaysomawat.careerhigh;


import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;


import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;



public class MainActivity extends ActionBarActivity {
    //private WebView mywebview;


    public class GeoWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // When user clicks a hyperlink, load in the existing WebView
            view.loadUrl(url);
            return true;
        }
    }

    //public class GeoWebChromeClient extends WebChromeClient {
    public class GeoWebChromeClient extends android.webkit.WebChromeClient {
        @Override
        public void onGeolocationPermissionsShowPrompt(String origin,
                                                       //GeolocationPermissions.Callback callback) {
                                                       android.webkit.GeolocationPermissions.Callback callback){
            // Always grant permission since the app itself requires location
            // permission and the user has therefore already granted it
            callback.invoke(origin, true, false);
        }
    }



    WebView mywebview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mywebview = (WebView)findViewById(R.id.webView);
        WebSettings webSettings = mywebview.getSettings();

        mywebview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        mywebview.getSettings().setBuiltInZoomControls(true);
        mywebview.setWebViewClient(new GeoWebViewClient());
        // Below required for geolocation
        mywebview.getSettings().setJavaScriptEnabled(true);
        mywebview.getSettings().setGeolocationEnabled(true);
        mywebview.setWebChromeClient(new GeoWebChromeClient());

        mywebview.getSettings().setAppCacheEnabled(true);
        mywebview.getSettings().setDatabaseEnabled(true);
        mywebview.getSettings().setDomStorageEnabled(true);

        mywebview.getSettings().setGeolocationDatabasePath(getFilesDir().getPath());


        mywebview.loadUrl("https://domoritz.github.io/leaflet-locatecontrol/demo/");

    }





    @Override
    public void onBackPressed(){
        if(mywebview.canGoBack()) {
            mywebview.goBack();
        } else
        {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item){
        int id = item.getItemId();

        if(id == R.id.action_settings){
            return true;
        }

        return super.onOptionsItemSelected(item);
    }



}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.vinaysomawat.careerhigh"
    android:installLocation="auto">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/faviconcircular"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/faviconcircular"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".SplashActivity" android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

        <activity android:name=".MainActivity" />
    </application>

</manifest>

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <WebView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/webView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />
</RelativeLayout>

How can I fix the geolocation problem? Thank you in advice.

Nicolaesse
  • 2,554
  • 12
  • 46
  • 71
  • It doesn't look like you show the android runtime permission dialog. Does your app ask the user at runtime for the Location Permission with a System Dialog? See this for reference: https://developer.android.com/guide/topics/permissions/overview#runtime – Alexander Hoffmann Nov 30 '21 at 09:02
  • It doesn't ask it, but I can't understand why. onGeolocationPermissionsShowPrompt should show the prompt to the user. – Nicolaesse Nov 30 '21 at 09:04
  • You have to explicitly do it yourself. Check the SO asnwers again which you have linked: https://stackoverflow.com/a/48661518/2258611 – Alexander Hoffmann Nov 30 '21 at 09:06

1 Answers1

1

Add this to your class with your permissions and then call it in onCreate

    private fun checkPermissions() {
    val permission = ActivityCompat.checkSelfPermission(
        this@MainActivity,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    )
    if (permission != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(
            this@MainActivity,
            permissions,
            requestExternalStorageCode
        )
    }
}

Also do not forget to override permissions callback to check if user granted you permissions:

    override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)

    if (requestCode == requestExternalStorageCode) {
        if (grantResults.size > 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //to whatever you need after the permission is granted
        } else {
            finish()
        }
    }
}