Android Studio:地理定位不起作用。无法在 Webview 中获取地理位置

Posted

技术标签:

【中文标题】Android Studio:地理定位不起作用。无法在 Webview 中获取地理位置【英文标题】:Android Studio: geolocation not working. Failing to get geolocation in 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>

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

问候

【问题讨论】:

【参考方案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;

    

【讨论】:

以上是关于Android Studio:地理定位不起作用。无法在 Webview 中获取地理位置的主要内容,如果未能解决你的问题,请参考以下文章

Cordova 地理定位插件在 android 设备上不起作用

android上的javascript地理定位在离线模式下不起作用

地理定位 API 在某些 Android 设备上不起作用

GPS 地理定位应用程序在 Android 的 Phonegap 中不起作用

原生离子地理定位有时不起作用

PhoneGAP 地理位置在 Android 中不起作用