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

Android Studio中WebView无法请求用户地理位置权限求助

解决WebView位置权限弹窗不显示的问题

第一步:清理并修正AndroidManifest.xml

你之前的Manifest里加了几个废弃或不必要的权限,先删掉冗余内容,保留核心权限即可:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.hav">
    <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" />
    <!-- 如果你的APP需要后台定位才打开下面这行,否则直接删掉 -->
    <!-- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> -->

    <application
        android:allowBackup="true"
        android:usesCleartextTraffic="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Hav">
        <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>
        <!-- 删掉那个你不知道填什么的service,完全不需要它 -->
    </application>
</manifest>

第二步:修改MainActivity.kt,添加权限请求逻辑

WebView不会自动弹出位置权限请求,必须手动处理权限申请,同时通过WebChromeClient承接网页的位置请求,直接在MainActivity里加代码就行,不用额外创建类:

package com.example.hav

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.webkit.GeolocationPermissions
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

class MainActivity : AppCompatActivity() {
    private val LOCATION_PERMISSION_REQUEST_CODE = 1001
    private lateinit var myWeb: WebView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        myWeb = findViewById<WebView>(R.id.myWebView)
        
        myWeb.webViewClient = WebViewClient()
        
        // 核心:自定义WebChromeClient处理网页的位置权限请求
        myWeb.webChromeClient = object : WebChromeClient() {
            override fun onGeolocationPermissionsShowPrompt(
                origin: String?,
                callback: GeolocationPermissions.Callback?
            ) {
                // 先检查有没有位置权限
                if (ContextCompat.checkSelfPermission(
                        this@MainActivity,
                        Manifest.permission.ACCESS_FINE_LOCATION
                    ) != PackageManager.PERMISSION_GRANTED &&
                    ContextCompat.checkSelfPermission(
                        this@MainActivity,
                        Manifest.permission.ACCESS_COARSE_LOCATION
                    ) != PackageManager.PERMISSION_GRANTED
                ) {
                    // 没有权限,弹出系统权限请求弹窗
                    ActivityCompat.requestPermissions(
                        this@MainActivity,
                        arrayOf(
                            Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION
                        ),
                        LOCATION_PERMISSION_REQUEST_CODE
                    )
                } else {
                    // 已有权限,直接允许网页获取位置
                    callback?.invoke(origin, true, false)
                }
            }
        }
        
        myWeb.apply{
            loadUrl("linktomywebsite.com")
            settings.javaScriptEnabled = true
            settings.setGeolocationEnabled(true)
        }
    }

    // 处理用户权限请求的结果
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
            // 如果用户同意了权限,通知WebView允许网页获取位置
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                myWeb.webChromeClient.onGeolocationPermissionsShowPrompt(
                    myWeb.url,
                    object : GeolocationPermissions.Callback {
                        override fun invoke(origin: String?, allow: Boolean, retain: Boolean) {
                            origin?.let { callback?.invoke(it, true, false) }
                        }
                    }
                )
            }
        }
    }
}

关键说明

  • WebView的位置请求必须通过WebChromeClient的回调触发,默认的客户端不会处理这个逻辑,所以必须自定义。
  • 不需要额外创建任何位置服务类,所有逻辑都在MainActivity里就能完成,不用纠结目录结构。
  • 当网页请求位置时,APP会先弹出系统权限弹窗,用户同意后网页就能正常获取位置了。

内容的提问来源于stack exchange,提问作者misha sachenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:40:22