android6.0定位失败,Android6.0(Api23)以后 WebView定位失效问题

Android WebView 加载网页url中,H5通过js获取位置定位信息。

/**

* 地图相关

*/

window.init = function() {

var map = new AMap.Map('mapContainer', {

resizeEnable: true,

zoom: 14

});

/*获取实时定位*/

map.plugin('AMap.Geolocation', function() {

geolocation = new AMap.Geolocation({

enableHighAccuracy: true, //是否使用高精度定位,默认:true

timeout: 10000, //超过10秒后停止定位,默认:无穷大

maximumAge: 0, //定位结果缓存0毫秒,默认:0

convert: true, //自动偏移坐标,偏移后的坐标为高德坐标,默认:true

showButton: true, //显示定位按钮,默认:true

buttonPosition: 'LB', //定位按钮停靠位置,默认:'LB',左下角

buttonOffset: new AMap.Pixel(10, 20), //定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)

showMarker: true, //定位成功后在定位到的位置显示点标记,默认:true

showCircle: true, //定位成功后用圆圈表示定位精度范围,默认:true

panToLocation: true, //定位成功后将定位到的位置作为地图中心点,默认:true

zoomToAccuracy: true //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false

});

map.addControl(geolocation);

geolocation.getCurrentPosition();

AMap.event.addListener(geolocation, 'complete', onComplete); //返回定位信息

AMap.event.addListener(geolocation, 'error', one rror); //返回定位出错信息

});

/*获取实时定位成功*/

function onComplete(data) {

var lng_my = data.position.lng;

var lat_my = data.position.lat;

var address_my = data.formattedAddress;

var address_province = data.addressComponent.province;

var address_city = data.addressComponent.city;

var address_district = data.addressComponent.district;

var address_township = data.addressComponent.township;

address_my = address_my.replace(address_province, '').replace(address_city, '').replace(address_district, '').replace(address_township, '');

var lnglat = gcj02towgs84(lng_my, lat_my);

var lnglat = gcj02towgs84(lng_my, lat_my);

$('#lng').val(lnglat[0]);

$('#lat').val(lnglat[1]);

$('#addrDetail').val(address_my);

}

/*获取实时定位失败*/

function one rror(data) {

mui.alert('请打开GPS!', ' ', '确定', function() {

removeDrop();

}, 'div');

$('.mui-popup').addClass('new-popup');

}

/*点击*/

var geocoder = null;

var clickHandler = function(e) {

if(!geocoder) {

geocoder = new AMap.Geocoder({

city: "济南", //城市设为北京,默认:“全国”

radius: 1000 //范围,默认:500

});

}

var lnglat = [];

lnglat.push(e.lnglat.getLng())

lnglat.push(e.lnglat.getLat())

geocoder.getAddress(lnglat, function(status, result) {

if(status === 'complete' && result.regeocode) {

var address = result.regeocode.formattedAddress;

var address_province = result.regeocode.addressComponent.province;

var address_city = result.regeocode.addressComponent.city;

var address_district = result.regeocode.addressComponent.district;

var address_township = result.regeocode.addressComponent.township;

address = address.replace(address_province, '').replace(address_city, '').replace(address_district, '').replace(address_township, '');

var btnArray = ['取消', '确认'];

mui.confirm('选中“' + address + '”?', ' ', btnArray, function(ee) {

$('.mui-popup-backdrop').hide()

if(ee.index == 1) {

var lnglat84 = gcj02towgs84(lnglat[0], lnglat[1]);

$('#lng').val(lnglat84[0]);

$('#lat').val(lnglat84[1]);

//回填位置信息

$('#addrDetail').val(address);

$('#mapContainer').addClass('mapContainer').removeClass('mapContainer-fullScreen');

returnPageOne();

addModel.step = 1;

hideErrorSymbol('addrDetail', '../img/icon/icon-located.png');

//显示第三页的单元信息

showUnitAmountInfo();

} else {

}

}, 'div');

$('.mui-popup').addClass('new-popup');

} else {

//alert(JSON.stringify(result))

}

});

};

// 绑定地图单击事件

map.on('click', clickHandler);

map.on('resize', function() {

map.setZoom(14);

});

}

以前也进行过H5需要位置信息的功能开发,不过以往的方案都是使用 Android 原生定位(集成高德/百度SDK),再将位置信息传给H5来实现,不过这次由于考虑到apk大小的问题(不再集成高德SDK)以及“懒”(不用再写定位的代码),所以就准备都让H5来做。本来认为这个方案应该是很简单的,没想到遇到了一个大坑——H5无法获取到位置信息。

1. 首先,想要获取位置信息,一定要来点定位权限!见代码

2. 在刚进入页面时,一般为onCreate()方法中,动态申请权限(我就不信你的app没有适配Android 6.0+)。在获取到权限后,再调用webview的loadUrl()比较稳妥~

3. webview相关代码

WebSettings webSettings = mWebView.getSettings();

// 允许调用 JS,因为网页地图使用的是 JS 定位

webSettings.setJavaScriptEnabled(true);

//启用数据库

webSettings.setDatabaseEnabled(true);

//启用地理定位,默认为true

webSettings.setGeolocationEnabled(true);

//设置定位的数据库路径

String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();

webSettings.setGeolocationDatabasePath(dir);

//开启DomStorage缓存

webSettings.setDomStorageEnabled(true);

mWebView.setWebChromeClient(new WebChromeClient() {

@Override

public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {

callback.invoke(origin, true, false);

super.onGeolocationPermissionsShowPrompt(origin, callback);

}

});

以上代码,自我感觉setJavaScriptEnabled()、setGeolocationEnabled()、setWebChromeClient()十分重要,其余的应该是可写可不写吧,不过没测试过。

4. 初步总结

第1步和第2步,主要是用于引导用户开启设备定位权限;第3步则是引导用户开启浏览器定位权限。

可但是!经过我代码的断点,设备定位权限获取到了,为什么没有走WebChromeClient中的onGeolocationPermissionsShowPrompt()方法?!!why??

5. 查阅资料

于是,我各种百度google,各种推荐将targetSdkVersion降到23,终于,我在官方讲解中发现:

d7ce9a97e7a2906e29ca549d5330295c.png

重点在这里:

Note that for applications targeting Android N and later SDKs (API level > Build.VERSION_CODES.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

标签:定位,lnglat,Api23,默认,address,var,WebView,true,Android6.0

来源: https://blog.csdn.net/qq_36158551/article/details/105294029

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值