Android使用WebView定位问题
作者:Typist夫少
链接:https://www.jianshu.com/p/d32d3641741f
来源:简书
最近遇到了一个问题,有一个需求是使用 WebView 来加载一个网页url,H5通过js来获取位置定位信息。以前也进行过H5需要位置信息的功能开发,不过以往的方案都是使用 Android 原生定位(集成高德/百度SDK),再将位置信息传给H5来实现,不过这次由于考虑到apk大小的问题(不再集成高德SDK)以及“懒”(不用再写定位的代码),所以就准备都让H5来做。本来认为这个方案应该是很简单的,没想到遇到了一个大bug——H5无法获取到位置信息。此时本想第一时间甩锅给H5(我的代码怎么可能会有问题?!!),然而iOS的好使,手机原生浏览器打开url也好使,顿时一脸懵逼,瞬间打脸。。。好吧,准备填坑吧~
1. 首先,想要获取位置信息,一定要来点定位权限!见代码
<!-- 网络权限,加载网络网页需要联网 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 粗略定位权限,允许一个程序通过网络获取粗略的位置 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 精确定位权限,允许一个程序访问精确位置(GPS定位) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
2. 在刚进入页面时,一般为onCreate()方法中,动态申请权限(我就不信你的app没有适配Android 6.0+)。在获取到权限后,再调用webview的loadUrl()比较稳妥~
3. webview相关代码
WebSettings webSettings = mWebView.getSettings();
//启用数据库
webSettings.setDatabaseEnabled(true);
//开启DomStorage缓存
webSettings.setDomStorageEnabled(true);
// 允许调用 JS,因为网页地图使用的是 JS 定位
webSettings.setJavaScriptEnabled(true);
//启用地理定位,默认为true
webSettings.setGeolocationEnabled(true);
//设置定位的数据库路径
String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
webSettings.setGeolocationDatabasePath(dir);
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
// 这里是处理是否同意定位权限,可以在这里写一个 AlertDialog 来模仿浏览器弹出来的定位权限申请。
callback.invoke(origin, true, false);
}
});
以上代码,自我感觉setJavaScriptEnabled()、setGeolocationEnabled()、setWebChromeClient()十分重要,其余的应该是可写可不写吧,不过没测试过
4. 初步总结
第1步和第2步,主要是用于引导用户开启设备定位权限;第3步则是引导用户开启浏览器定位权限。
(重点来了!!!)
可但是!经过我代码的断点,设备定位权限获取到了,为什么没有走WebChromeClient中的onGeolocationPermissionsShowPrompt()方法?!!why??(黑人问号脸)
5. 查阅资料
于是,我各种百度google,各种推荐将targetSdkVersion降到23,然而士可杀不可辱,若非要辱,至少告诉我,为什么要辱!终于,我在官方讲解中发现:
重点在这里:
Note that for applications targeting Android N and later SDKs (API level >
[Build.VERSION_CODES.M](https://developer.android.com/reference/android/os/Build.VERSION_CODES.html#M)
) this method is only called for requests originating from secure origins such as https. On non-secure origins geolocation requests are automatically denied.
翻译如下:
注意,对于针对Android N和以后的SDKs (API级别> Build.VERSION_CODES.M)的应用程序,此方法仅对来自安全源(如https)的请求调用。在非安全源上,将自动拒绝地理位置请求。
好吧,我的H5的url是“http”开头,被自动屏蔽了。怎么样,惊不惊喜,意不意外?!
6. 总结
WebView定位的解决方案:
方案一:webview的定位,乖乖的使用原生的定位方法,之后将位置信息传递到H5~
方案二:使用高德地图的辅助H5页面定位,已经测试过,可行!
方案三:降低targetSdkVersion版本到23,要求较低的懒人法
方案四:升级http到https
推荐阅读
-
Android编程实现使用webView打开本地html文件的方法
-
android使用百度地图SDK获取定位信息示例
-
Android GPS室内定位问题的解决方法(location为null)
-
详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题
-
Android 中ViewPager中使用WebView的注意事项
-
Android编程实现使用webView打开本地html文件的方法
-
android使用百度地图SDK获取定位信息示例
-
Android 解决WebView调用loadData()方法显示乱码的问题
-
Android GPS室内定位问题的解决方法(location为null)
-
Android开发中使用WebView控件浏览网页的方法详解