【问题标题】:Android Studio: geolocation not working. Failing to get geolocation in WebviewAndroid Studio:地理定位不起作用。无法在 Webview 中获取地理位置
【发布时间】:2019-07-16 15:44:58
【问题描述】:

我正在使用 WebView 来显示不同的 html 页面。在这些我正在从 mapbox 实现地图,但它不会找到用户的位置。 即使我在 WebView 中打开不同的 https 页面,也永远不会在这些方面找到位置。 我允许位置权限并向 Android Manifest 添加不同的用户权限。

这些页面可以很好地定位我的设备的位置,如果我没有从我正在处理的应用程序中的 WebView 打开它们。

我自己创建的页面包含一个与leaflet.com 的api 配合使用的地图。

这是一些我试图让它工作的简单代码。

import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TextView mTextMessage;

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_home:
                    mTextMessage.setText(R.string.title_home);
                    return true;
                case R.id.navigation_dashboard:
                    mTextMessage.setText(R.string.title_dashboard);
                    return true;
                case R.id.navigation_notifications:
                    mTextMessage.setText(R.string.title_notifications);
                    return true;
            }
            return false;
        }
    };

    private WebView mWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WebView myWebView = (WebView) findViewById(R.id.map);
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setGeolocationEnabled(true);
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        webSettings.setBuiltInZoomControls(true);
        webSettings.setGeolocationEnabled(true);
        //myWebView.loadUrl("file:///android_asset/leaflet.html");
        myWebView.loadUrl("https://mylocation.org");

        mTextMessage = (TextView) findViewById(R.id.message);
        BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    }

}

这是 manifest.xml 的代码,我在其中提供了不同的用户权限

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

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


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

我希望有人可以帮助我,因为我花了好几个小时来解决这个问题。互联网上几乎没有任何问题接近这个或任何解决方案。

问候

【问题讨论】:

    标签: java android html geolocation


    【解决方案1】:

    您需要设置一个 WebChromeClient 方法来请求相应的权限:

    private String geolocationOrigin;
    private GeolocationPermissions.Callback geolocationCallback;
    
    WebSettings webSettings = webView.getSettings();
    
    //required for Geolocation
    webSettings.setGeolocationEnabled(true);
    webView.setWebChromeClient(new MyGeoWebChromeClient());
    
    
    public class MyGeoWebChromeClient 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;
                }
            }
        }
    }
    
    @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;
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-05
      • 2017-04-04
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      相关资源
      最近更新 更多