Update: 2017/12/4 16:20
突然想到了很多坑,先來占個位置。
1行疏、當手機沒有打開定位服務的時候,必須先要打開定位服務套像。參考:LocationService
酿联。
2、定位服務還可能分多種夺巩,根據(jù)具體需求做相關(guān)處理贞让。
- only GPS
- WLAN && cellular networks
- GPS && WLAN && cellular networks
最近遇到了一個問題,有一個需求是使用
WebView
來加載一個網(wǎng)頁地圖定位柳譬。以前都是使用 Android 原生的來開發(fā)(當然這種最好)喳张,不過各個方面都能行那更好嘛。想想應該很簡單美澳,然而一不小心就掉進了一個大坑销部,地圖無法定位(這里一般我都會想肯定是這個網(wǎng)頁的鍋)。然而IOS
端可以制跟,這個坑就只能自己填了舅桩。
第一步,百度(谷歌要翻墻雨膨,而且公司網(wǎng)速巨慢)擂涛,一看一大堆。照著敲一敲聊记。這里我說一些必要的吧撒妈。如果你搜過了,你可以直接看文章末尾甥雕。
權(quán)限
<!-- 網(wǎng)絡權(quán)限踩身,加載網(wǎng)絡網(wǎng)頁需要聯(lián)網(wǎng) -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 粗略定位權(quán)限,允許一個程序訪問CellID或WiFi熱點來獲取粗略的位置 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 精確定位權(quán)限社露,允許一個程序訪問精良位置(如GPS) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
注意:定位權(quán)限屬于危險權(quán)限挟阻,在 Android 6.0 之后需要在代碼中動態(tài)申請。
具體代碼
mWebView = findViewById(R.id.web_view);
WebSettings settings = mWebView.getSettings();
// 允許調(diào)用 JS,因為網(wǎng)頁地圖使用的是 JS 定位
settings.setJavaScriptEnabled(true);
// 允許使用數(shù)據(jù)庫
settings.setDatabaseEnabled(true);
settings.setGeolocationEnabled(true);
String dir = getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath(); settings.setGeolocationDatabasePath(dir);
settings.setDomStorageEnabled(true);
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
// 這里是處理是否同意定位權(quán)限附鸽,可以在這里寫一個 AlertDialog 來模仿瀏覽器彈出來的定位權(quán)限申請脱拼。
//public void invoke(String origin, boolean allow, boolean retain);
callback.invoke(origin, true, false);
}
});
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return super.shouldOverrideUrlLoading(view, url);
}
});
好了寫到這里也就大功告成了,然而一運行坷备,卻失敗了熄浓。最開始我以為是這個網(wǎng)頁的鍋。然而我用手機自帶瀏覽器打開居然可以省撑,它會彈出一個窗口如下:
還以為是這個的原因了赌蔑,可是我不是 callback.invoke(origin, true, false);
同意了么。其實和這個沒關(guān)系...
這里是文章末尾
今天早上我突然在錘子(API level 19)設置里面看到了一個定位服務竟秫,打開之后就在上面運行成功了娃惯,十分興奮。然而還有一個大坑等著我肥败,我又在我的紅米(API level 24) 上面運行了一下趾浅,失敗了。萬分苦惱馒稍,搜索出來的結(jié)果都是千篇一律的皿哨,可是為什么我失敗了了?漫無目的的在網(wǎng)上瀏覽纽谒,沒想到還真找到了证膨。
文章地址:http://www.reibang.com/p/798cbc2b27a9
在文章末尾說到了將 targetSdkVersion
改為 23 就可以了。我的是 26鼓黔。一改椎例,果然成功。
這一系列的現(xiàn)象讓我離真理又進了一步请祖。想起還看到了一個過時方法:setGeolocationDatabasePath
。然后去查了查這個方法脖祈,果然是它的鍋肆捕。
setGeolocationDatabasePath
added in API level 5
deprecated in API level 24
API level 5 ~ 23
This will update WebCore when the Sync runs in the C++ side.
API level 24 ~ Now
Geolocation database are managed by the implementation and calling this method will have no effect.
Sets the path where the Geolocation databases should be saved. In order for Geolocation permissions and cached positions to be persisted, this method must be called with a path to which the application can write.
Parameters | |
---|---|
databasePath | String: a path to the directory where databases should be saved. |
void setGeolocationDatabasePath (String databasePath)
Parameters | |
---|---|
databasePath | String: a path to the directory where databases should be saved. |
這里英文很簡單,就不翻譯了(其實是懶(o)/~)盖高,大致意思是說慎陵,這個方法在 API level 24 的時候被廢棄了,需要自己去實現(xiàn)管理這個數(shù)據(jù)庫喻奥。然而我不會┓( ?
)┏席纽。于是就只有改成了 targetSdkVersion:23
。
targetSdkVersion 的作用自己去百度吧撞蚕。
好像也可以代碼中動態(tài)來處理润梯,有興趣的可以去試試。
堅持寫了這么多,扛不住了纺铭,先溜了~寇钉!