You need to enable JavaScript to run this app. WebView封装的安卓应用无法自动获取当前定位的问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

WebView封装的安卓应用无法自动获取当前定位的问题咨询

问题描述

通过WebView封装地址为https://taxif.com/online.html的页面后,出现普通浏览器可自动获取定位、封装应用内无法自动定位的异常,需求是实现与网页端一致的WebView自动定位能力。提前感谢各位的解答。


附带代码片段

MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;


public class MainActivity extends AppCompatActivity {
    private SwipeRefreshLayout refreshLayout;
    private WebView webView;

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

        webView = findViewById(R.id.myWebView);
        refreshLayout = findViewById(R.id.refresh);

        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                webView.reload();
            }
        });

        webView.getSettings().setLoadWithOverviewMode(true);
        webView.getSettings().setUseWideViewPort(true);


        webView.setWebChromeClient(new MyChromeClient());
        webView.setWebViewClient(new BrowserClient(refreshLayout));

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setAppCacheEnabled(true);

        webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        webSettings.setAppCacheEnabled(true);
        webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        webSettings.setSavePassword(true);
        webSettings.setSaveFormData(true);
        webSettings.setEnableSmoothTransition(true);

        loadWebPage();

    }

    private void loadWebPage() {

        ConnectivityManager connectivityManager = (ConnectivityManager) MainActivity.this
                .getApplication().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

        if(networkInfo != null && networkInfo.isConnectedOrConnecting()){
            webView.loadUrl("https://taxif.com/online.html");
        }else{
            Toast.makeText(this,"You don't have any active internet connection",Toast.LENGTH_SHORT).show();
        }
    }
}

BrowserClient.java

import android.graphics.Bitmap;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

public class BrowserClient extends WebViewClient {

    SwipeRefreshLayout refreshLayout;

    public BrowserClient(){

    }

    public BrowserClient(SwipeRefreshLayout refreshLayout) {
        this.refreshLayout = refreshLayout;
    }

    @Override
    public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
        super.onReceivedError(view, request, error);
    }

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        super.onPageStarted(view, url, favicon);
        refreshLayout.setRefreshing(true);
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        refreshLayout.setRefreshing(false);
    }
}

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.booking">

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


    <uses-feature android:name="android.hardware.type.watch" />

    <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/Theme.BookingApp">

        <!--
               Set to true if your app is Standalone, that is, it does not require the handheld
               app to run.
        -->
        <meta-data
            android:name="com.google.android.wearable.standalone"
            android:value="true" />

        <activity
            android:name=".SplashScreen"
            android:label="Booking App"><intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

        </activity>
    </application>

</manifest>

实现方案

异常根源为WebView默认未开启定位能力透传、未处理网页发起的定位权限请求,需完成4项配置:

  • 开启WebSettings定位开关
    在已有的WebSettings初始化代码块中追加以下配置:
    // 开启WebView定位能力
    webSettings.setGeolocationEnabled(true);
    // 开启DOM存储,避免部分网页定位依赖的本地标识无法缓存
    webSettings.setDomStorageEnabled(true);
    
  • 重写WebChromeClient的定位权限回调
    你代码中已初始化MyChromeClient,需在该类中补充以下重写逻辑:
    import android.webkit.GeolocationPermissions;
    import android.webkit.WebChromeClient;
    
    public class MyChromeClient extends WebChromeClient {
        @Override
        public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
            // 检查系统定位权限是否已授予
            if (checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) == android.content.pm.PackageManager.PERMISSION_GRANTED
                    && checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) == android.content.pm.PackageManager.PERMISSION_GRANTED) {
                // 权限已授予,直接允许网页定位请求
                callback.invoke(origin, true, false);
            } else {
                // 未授予权限,发起系统权限申请
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION},
                        1001);
            }
        }
    }
    
  • 补充权限申请结果处理逻辑
    在MainActivity中添加权限回调方法,确保用户授权后页面可正常触发定位:
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1001) {
            if (grantResults.length > 0 && grantResults[0] == android.content.pm.PackageManager.PERMISSION_GRANTED) {
                // 授权完成后刷新页面,重新触发起始的定位请求
                webView.reload();
            } else {
                Toast.makeText(this, "未授予定位权限,无法获取当前位置", Toast.LENGTH_SHORT).show();
            }
        }
    }
    
  • 清理冗余配置
    删除MainActivity中重复调用的webSettings.setAppCacheEnabled(true)代码行;如果应用为普通手机端应用,删除AndroidManifest中手表相关的<uses-feature android:name="android.hardware.type.watch" />及对应手表meta-data配置,避免硬件校验异常。

内容的提问来源于stack exchange,提问作者Rehan Shakir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.06 13:24:02