WebView处理网页位置请求

随着移动设备的激增,LBS(Location Based Service)已然成为趋势,其最关键的还是获取设备的位置信息。native代码获取位置信息轻轻松松可以搞定,实际上网页获取位置信息也不是那么困难。

在HTML5中,提供了一套定位用户信息的接口,当然这个位置信息是通过客户端,准确说是浏览器获取的。

注意,位置信息属于个人隐私的范围,只有经过用户同意之后才能获取到信息。

网页如何实现请求位置信息

使用getCurrentPosition()方法来请求位置信息。 下面是一个很简单的示例,来展示用户位置信息的经度和纬度。

lineos:false

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42

<!DOCTYPE html> <html> <body> <p id="demo">Click the button to get your coordinates:</p> <button onclick="getLocation()">Try It</button> <script> var x = document.getElementById("demo"); function getLocation() { console.info("getLocation working") if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(showPosition,showError); } else { x.innerHTML = "Geolocation is not supported by this browser."; } } function showPosition(position) { x.innerHTML="Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude; } function showError(error) { switch(error.code) { case error.PERMISSION_DENIED: x.innerHTML = "User denied the request for Geolocation." break; case error.POSITION_UNAVAILABLE: x.innerHTML = "Location information is unavailable." break; case error.TIMEOUT: x.innerHTML = "The request to get user location timed out." break; case error.UNKNOWN_ERROR: x.innerHTML = "An unknown error occurred." break; } } </script> </body> </html>

示例阐述

  • 检测getLocation方法是否可用
  • 如果可以调用getCurrentPosition方法,否则提示浏览器不支持
  • 如果getCurrentPosition获取信息成功,返回一个坐标系的对象,并将这个对象作为参数传递到showPosition方法,如果失败,调用showError方法,并将错误码作为showError方法的参数。
  • showPosition方法展示经度和纬度信息
  • showError方法用来处理请求错误

上述部分参考自html5_geolocation w3cschool,更多高级操作请访问左侧链接。

WebView如何返回给网页

大致操作步骤

  • 在manifest中申请android.permission.ACCESS_FINE_LOCATION 或 android.permission.ACCESS_COARSE_LOCATION 权限。两者都有更好。
  • 设置webivew开启javascript功能,地理定位功能,设置物理定位数据库路径
  • 在onGeolocationPermissionsShowPrompt处理物理位置请求,常用的是提示用户,让用户决定是否允许。

使用的API

  • android.permission.ACCESS_FINE_LOCATION 通过GPS,基站,Wifi等获取精确的位置信息。
  • android.permission.ACCESS_COARSE_LOCATION 通过基站,Wifi等获取错略的位置信息。
  • onGeolocationPermissionsShowPrompt 位置信息请求回调,通常在这里弹出选择是否赋予权限的对话框
  • GeolocationPermissions.Callback.invoke(String origin, boolean allow, boolean remember)决定是否真正提供给网页信息,可根据用户的选择结果选择处理。 实现代码

lineos:false

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

final WebView webView = new WebView(this); addContentView(webView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT) ); WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true); settings.setGeolocationEnabled(true); settings.setGeolocationDatabasePath(getFilesDir().getPath()); webView.setWebChromeClient(new WebChromeClient() { @Override public void onGeolocationPermissionsHidePrompt() { super.onGeolocationPermissionsHidePrompt(); Log.i(LOGTAG, "onGeolocationPermissionsHidePrompt"); } @Override public void onGeolocationPermissionsShowPrompt(final String origin, final Callback callback) { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setMessage("Allow to access location information?"); OnClickListener dialogButtonOnClickListener = new OnClickListener() { @Override public void onClick(DialogInterface dialog, int clickedButton) { if (DialogInterface.BUTTON_POSITIVE == clickedButton) { callback.invoke(origin, true, true); } else if (DialogInterface.BUTTON_NEGATIVE == clickedButton) { callback.invoke(origin, false, false); } } }; builder.setPositiveButton("Allow", dialogButtonOnClickListener); builder.setNegativeButton("Deny", dialogButtonOnClickListener); builder.show(); super.onGeolocationPermissionsShowPrompt(origin, callback); Log.i(LOGTAG, "onGeolocationPermissionsShowPrompt"); } }); webView.loadUrl("file:///android_asset/geolocation.html");

疑问解答

I/SqliteDatabaseCpp(21863): sqlite returned: error code = 14

原因是你没有设置setGeolocationDatabasePath,按照上面例子设置即可。

点击之后没有任何变化

  • 检查代码是否按照上面一样,是否有错误。
  • 在第一次请求的是否,需要的反应时间比较长。

检测定位服务是否可用

当GPS_PROVIDER和NETWORK_PROVIDER有一者可用,定位服务就可以用,当两者都不能用时,即定位服务不可以用。 注意PASSIVE_PROVIDER不能作为定位服务可用的标志。因为这个provider只会返回其他Provider提供的位置信息,自己无法定位。

lineos:false

1 2 3 4 5 6 7

private void testGeolocationOK() { LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); boolean gpsProviderOK = manager.isProviderEnabled(LocationManager.GPS_PROVIDER); boolean networkProviderOK = manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); boolean geolocationOK = gpsProviderOK && networkProviderOK; Log.i(LOGTAG, "gpsProviderOK = " + gpsProviderOK + "; networkProviderOK = " + networkProviderOK + "; geoLocationOK=" + geolocationOK); }

跳转到位置设置界面

我们只需要发送一个简单的隐式intent即可启动位置设置界面

lineos:false

1 2

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

示例代码

百度云盘

其他

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C#

免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)

    在生活中有一种东西几乎已经快要成为我们的另一个电子”身份证“,那就是二维码。无论是在软件开发的过程中,还是在普通用户的日常中,几乎都离不开二维码。...

1.6K90
来自专栏岑志军的专栏

TTTAttributedLabel高亮显示手机号码、网址

23630
来自专栏杂烩

分布式服务框架之Dubbo整合Spring项目(二)

12020
来自专栏五毛程序员

五毛的cocos2d-x学习笔记08-动画

20850
来自专栏Android干货园

一款基于Material Desgin设计的APP

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/50...

23210
来自专栏Android小菜鸡

Android语音录制,语音发送

这是一个录音的例子,可用于IM的语音发送,OA的语音留言等。 首先我们需要引入权限:

60520
来自专栏浅探ARKit

ARKit中控制.dae动画的播放

4.用时间控制动画--CAAnimation 里的 timeOffset 控制开始时间 duration控制播放时间

82970
来自专栏Rindew的iOS技术分享

iOS地图找房(类似链家、安居客等地图找房)

36560
来自专栏LeoXu的博客

让 Android 的 WebView 支持 type 为 file 的 input,同时支持拍照

Android 的 WebView 组件默认是不启用 type 为 file 的 input 的,需要在代码中做一些类似 hack 的编码(因为解决问题的目标对...

15420
来自专栏Java成神之路

Java微信公众平台开发_04_自定义菜单

自定义菜单中请求包的数据是Json字符串格式的,请参见:  Java_数据交换_fastJSON_01_用法入门

17930

扫码关注云+社区

领取腾讯云代金券