Android WebView 中的 Html 網(wǎng)頁定位操作

利用 HTML5 提供的定位 API 可以幫助網(wǎng)頁獲取用戶設(shè)備的當(dāng)前位置信息。但如果是在 Android 系統(tǒng)下的應(yīng)用中打開網(wǎng)頁,我們使用 Hybrid 開發(fā)模式時用到的 WebView 包括應(yīng)用本身都需要做一定的設(shè)置才能支持內(nèi)嵌網(wǎng)頁的定位功能。

這里是一個簡單的網(wǎng)頁源碼,其中有一段 JavaScript 代碼,用于向宿主瀏覽器請求定位:

<!DOCTYPE html>
<head>
</head>
<body>
    <button onclick="fetchLocation()">獲取位置</button>
    <script>
        var tipsEle = document.getElementById('tips')
        function fetchLocation() {
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(onGeoSuccess, onGeoError)
            } else {
                alert('當(dāng)前設(shè)備不支持定位!')
            }
        }
        function onGeoSuccess(event){
            alert("Success: " + event.coords.latitude + ", " + event.coords.longitude)
        }
        function onGeoError(event){
            alert("Error code " + event.code + ". " + event.message)
        }
    </script>
</body>

簡單說明:(有關(guān) HTML5 定位 API 的詳細(xì)使用,可以參考鏈接:菜鳥教程 - HTML5 Geolocation

  • navigator.geolocation 屬性判斷當(dāng)前硬件瀏覽器環(huán)境是否支持定位;

  • getCurrentPosition() 函數(shù),在支持定位的前提下,發(fā)起請求定位,并傳遞定位成功和失敗兩個函數(shù)作為回調(diào)參數(shù)。

然后在我們的 WebView 中添加如下設(shè)置:(這里假設(shè)上面的測試 html 文件放置在 assets 目錄下)

WebView contentWv = (WebView) findViewById(R.id.wv_content);
WebSettings settings = contentWv.getSettings();
settings.setJavaScriptEnabled(true);
contentWv.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        callback.invoke(origin, true, true);
        super.onGeolocationPermissionsShowPrompt(origin, callback);
    }
});
contentWv.loadUrl("file:///android_asset/location.html");

代碼很簡單,最重要的一個地方就是,重寫 WebChromeClient 的這個方法:

onGeolocationPermissionsShowPrompt()

當(dāng)網(wǎng)頁發(fā)起定位請求時,會調(diào)用到宿主 WebView 的這個方法,由開發(fā)者自行處理這個請求??梢钥吹剑纠邪@么一行代碼:

callback.invoke(origin, true, true);

這行代碼就是用來處理定位請求,一般會向用戶給出一個請求定位權(quán)限的彈窗。第二個 boolean 類型的參數(shù)表示是否授予網(wǎng)頁定位權(quán)限;而第三個 boolean 類型的參數(shù)則表示是否保留這個權(quán)限狀態(tài)。

值得注意的是,第三個參數(shù)的設(shè)置影響的是整個應(yīng)用中的 WebView。如果我們在某個頁面的 WebView 中處理過一次網(wǎng)頁的定位請求,并設(shè)置第三個參數(shù)為 true,即保留狀態(tài)的情況下,當(dāng)下次在其他頁面或者還是這個頁面打開網(wǎng)頁時將不再向用戶發(fā)起定位權(quán)限的請求,而是直接執(zhí)行定位操作。

一般比較合適的做法是,在該回調(diào)函數(shù)中設(shè)置一個對話框,告知用戶是否授權(quán)定位操作。做得更好一點的話,還可以幫助用戶檢測設(shè)備的系統(tǒng)定位是否打開。沒有打開的情況下,提示用戶并跳轉(zhuǎn)至設(shè)置界面。

檢測系統(tǒng)定位是否打開的示例代碼:

private boolean isSystemLocationEnable() {
    LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    boolean gpsLocationEnable = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    boolean networkLocationEnable = manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    return gpsLocationEnable && networkLocationEnable;
}

跳轉(zhuǎn)至系統(tǒng)設(shè)置中的定位界面:

Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);

還有最后一步,別忘了在 Manifest 清單文件中添加定位相關(guān)的權(quán)限,當(dāng)然也包括網(wǎng)絡(luò)權(quán)限:(通過 GPS 精準(zhǔn)定位和 WI-FI 的粗略定位)

<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"/>

這段示例網(wǎng)頁代碼調(diào)用時的效果如圖:

整體看來,使用方式還挺簡單的,那是不是這種方式就一定萬無一失呢?

前面提過,使用 HTML5 定位 API 獲取用戶位置的前提是瀏覽器或者說我們 Android 系統(tǒng)中的原生 WebView 環(huán)境支持定位操作。事實上,經(jīng)測試,這種方式不完全穩(wěn)定。尤其是在國內(nèi)各種廠商各種 ROM 的復(fù)雜環(huán)境下,還是有相當(dāng)多品牌的手機是不支持這種定位操作的。甚至,你還會遇見,即使是使用同一臺手機,安裝不同的瀏覽器 App 對于定位的支持也不盡相同。

所以,HTML5 自身的定位操作只能作為一種輔助手段。更穩(wěn)妥的做法是,開發(fā)人員通過百度、高德之類的第三方定位 SDK 在原生代碼中獲取用戶位置信息,當(dāng)打開 WebView 中的網(wǎng)頁時通過拼接 URL 參數(shù)的形式傳遞給網(wǎng)頁。網(wǎng)頁自行判斷,如果 URL 中不包含定位信息的話,再通過自身的 API 發(fā)起定位請求。

或者通過HTML 網(wǎng)頁的 JS代碼 與 Java 原生代碼交互的方式間接操作。關(guān)于 JS 與 Java 交互的相關(guān)知識,可以參考我的這篇文章:

Android WebView —— Java 與 JavaScript 交互總結(jié)

關(guān)于我:亦楓,博客地址:http://yifeng.studio/,新浪微博:IT亦楓

微信掃描二維碼,歡迎關(guān)注我的個人公眾號:安卓筆記俠

不僅分享我的原創(chuàng)技術(shù)文章,還有程序員的職場遐想

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容