Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm working on an Android Project. Basically, I'm trying to run WebView that displays Google Maps.

I wanted to display my own location but when I press the button for this, I get exceptions like:

11-18 17:29:56.237 7678-7678/com.example.ali.bellsolution E/LocationProvider: Caught security exception while registering for location updates from the system. The application does not have sufficient geolocation permissions.
11-18 17:29:56.257 7678-7678/com.example.ali.bellsolution E/LocationProvider: Caught security exception while registering for location updates from the system. The application does not have sufficient geolocation permissions.
11-18 17:29:56.260 7678-7678/com.example.ali.bellsolution E/LocationProvider: Caught security exception while registering for location updates from the system. The application does not have sufficient geolocation permissions.

I have added these permissions to the manifest 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" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

MainActivity.java:

package com.example.ali.bellsolution;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MainActivity extends Activity {

    private static final int REQUEST_FINE_LOCATION = 0;

    WebView myWebView;

    String mapPath = "https://www.google.co.uk/maps/@51.5112044,-0.2712415,14z";

    /**
     * WebViewClient subclass loads all hyperlinks in the existing WebView
     */
    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;
        }
    }



    /**
     * WebChromeClient subclass handles UI-related calls
     * Note: think chrome as in decoration, not the Chrome browser
     */
    public class GeoWebChromeClient extends WebChromeClient {
        @Override
        public void onGeolocationPermissionsShowPrompt(String origin,
                                                       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);
        }
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {



        super.onCreate(savedInstanceState);

        loadPermissions(Manifest.permission.ACCESS_COARSE_LOCATION, REQUEST_FINE_LOCATION);

        setContentView(R.layout.activity_main);
        myWebView = (WebView) this.findViewById(R.id.mapview);


        myWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        myWebView.getSettings().setBuiltInZoomControls(true);
        myWebView.setWebViewClient(new GeoWebViewClient());



        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.getSettings().setGeolocationEnabled(true);
        myWebView.setWebChromeClient(new GeoWebChromeClient());
        myWebView.loadUrl(mapPath);

    }

    @Override
    public void onBackPressed() {
        // Pop the browser back stack or exit the activity
        if (myWebView.canGoBack()) {
            myWebView.goBack();
        }
        else {
            super.onBackPressed();
        }
    }


    private void loadPermissions(String perm, int requestCode) {
        if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
            if (!ActivityCompat.shouldShowRequestPermissionRationale(this, perm)) {
                ActivityCompat.requestPermissions(this, new String[]{perm}, requestCode);
            }
        }
    }



}

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ali.bellsolution" >



    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="23" />



    <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" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="WebViewApp"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity"
                  android:label="WebViewApp"
            >

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
372 views
Welcome To Ask or Share your Answers For Others

1 Answer

You may want to ask the user for Geolocation permissions right when they are needed, but wait for the user's response before invoking the Callback:

private static final int REQUEST_FINE_LOCATION = 1;
private String geolocationOrigin;
private GeolocationPermissions.Callback geolocationCallback;

public class GeoWebChromeClient extends WebChromeClient {
    @Override
    public void onGeolocationPermissionsShowPrompt(String origin,
                                                   GeolocationPermissions.Callback callback) {
        // Geolocation permissions coming from this app's Manifest will only be valid for devices with
        // API_VERSION < 23. On API 23 and above, we must check for permissions, and possibly
        // ask for them.
        String perm = Manifest.permission.ACCESS_FINE_LOCATION;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
                ContextCompat.checkSelfPermission(MainActivity.this, perm) == PackageManager.PERMISSION_GRANTED) {
            // we're on SDK < 23 OR user has already granted permission
            callback.invoke(origin, true, false);
        } else {
            if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, perm)) {
                // ask the user for permission
                ActivityCompat.requestPermissions(MainActivity.this, new String[] {perm}, REQUEST_FINE_LOCATION);

                // we will use these when user responds
                geolocationOrigin = origin;
                geolocationCallback = callback;
            }
        }
    }
}

and receive the result of the permission request:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
    case REQUEST_FINE_LOCATION:
        boolean allow = false;
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // user has allowed this permission
            allow = true;
        }
        if (geolocationCallback != null) {
            // call back to web chrome client
            geolocationCallback.invoke(geolocationOrigin, allow, false);
        }
        break;
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...