You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android WebView地理位置获取异常问题求助

问题解决:WebView无法弹出位置权限请求导致位置为空

问题概述

开发的位置获取应用在网页端正常运行,但通过Android WebView实现时,未弹出位置权限请求,导致位置信息为空。

核心问题与解决方案

  • 缺少动态权限申请:Android 6.0及以上版本中,位置权限属于危险权限,仅在Manifest声明不够,必须主动向用户申请。
  • WebView未启用必要设置:网页定位依赖JavaScript,需开启JS支持、地理定位功能及DOM存储。
  • 代码细节缺失:未定义日志TAG、未在权限就绪后加载网页。

修改后的代码

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 100;
    private WebView myWebView;

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

        myWebView = findViewById(R.id.webView);
        // 配置WebView基础设置
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true); // 网页定位依赖JS
        webSettings.setGeolocationEnabled(true); // 开启地理定位支持
        webSettings.setDomStorageEnabled(true); // 部分网页定位需DOM存储

        // 检查并申请位置权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                    LOCATION_PERMISSION_REQUEST_CODE);
        } else {
            // 权限已授予,加载网页
            setupWebChromeClientAndLoadUrl();
        }
    }

    private void setupWebChromeClientAndLoadUrl() {
        myWebView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onGeolocationPermissionsShowPrompt(final String origin, final GeolocationPermissions.Callback callback) {
                Log.i(TAG, "onGeolocationPermissionsShowPrompt()");

                final boolean remember = false;
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setTitle("位置权限请求")
                        .setMessage("是否允许应用获取你的当前位置?")
                        .setCancelable(true)
                        .setPositiveButton("允许", (dialog, id) -> callback.invoke(origin, true, remember))
                        .setNegativeButton("拒绝", (dialog, id) -> callback.invoke(origin, false, remember));
                AlertDialog alert = builder.create();
                alert.show();
            }
        });
        myWebView.loadUrl("https://rkjrrampur.in/bobby/4a-track.html");
    }

    // 处理权限申请结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                setupWebChromeClientAndLoadUrl();
            } else {
                Toast.makeText(this, "位置权限被拒绝,无法获取位置信息", Toast.LENGTH_SHORT).show();
                myWebView.loadUrl("https://rkjrrampur.in/bobby/4a-track.html");
            }
        }
    }
}

AndroidManifest.xml(优化版本)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <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"/>
    <!-- 若需后台定位(Android 10+),添加以下权限 -->
    <!-- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> -->

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.BOBBYTRACK"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

activity_main.xml(无需修改)

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="0dp"
        android:minHeight="4dp"
        android:padding="0dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <WebView
        android:id="@+id/webView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/progressBar" />

</androidx.constraintlayout.widget.ConstraintLayout>

关键说明

  1. 动态权限申请:必须在运行时请求位置权限,否则WebView无法调用系统定位能力。
  2. WebView配置:启用JavaScript是网页定位的前提,同时开启地理定位和DOM存储确保网页逻辑正常运行。
  3. 权限时序处理:等待用户授予权限后再加载网页,避免权限未就绪时定位请求失败。

内容的提问来源于stack exchange,提问作者shrey bassi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 10:01:09