/SimpleLocation

定位功能和反地理编码功能

Primary LanguageJava

SimpleLocation

本篇主要介绍谷歌自带的LocationManager 获取手机定位的方法,以及通过谷歌服务Geocoder 来进行反地理编码。接口api都比较简单,细节可以查看代码。

其实LocationManager 的api使用起来很简单,难点在于不同android机型,不同系统可能存在着很多未知的坑。最大的坑就是有的手机系统底层的定位服务是直接连接的google服务器,手机厂商没有将定位的服务器重定向为国内的定位服务商,致使我们通过LocationManager根本拿不到定位信息。针对这种情况,我在项目里,提供了基站定位的方式来获取当前的经纬度信息。通过mmc、mnc、lac、cid来查询基站信息的服务器,使用的是cellocation.com api免费接口,但是由于近期19/09/05无法进行访问,所以我又提供了调用openCellid 服务器的api接口来进行基站地位。

由于Geocoder 进行反地理编码需要一个未包含在android核心框架之中的后端服务,如果平台中没有这个后端服务,Geocoder查询方法将返回空列表。不幸的是,国内很多手机厂商都没有内置这种服务(例如百度、高德服务),所以Geocoder也就不能使用了。针对这种情况,我在demo里除了提供了Geocoder 之外,又额外添加了高德反地理编码api,腾讯反地理编码api,百度反地理编码api,白名单方式和sn签名校验方式都有。大家只需要传入申请的key即可。大家也可以将项目的依赖直接打包成jar包使用。

这里贴下使用获取经纬度方法的代码片段:

        GeocodingManager.GeoOption option = new GeocodingManager.GeoOption()
                .setGeoType(Constant.LM_API) // 使用openCellid服务器的基站地位
                .setOption(new GoogleGeocoding.SiLoOption()
                        .setGpsFirst(true));// locationManager定位方式时,gps优先
        siLoManager = new GeocodingManager(this, option);
        siLoManager.start(new IGeocoding.ISiLoResponseListener() {
            @Override
            public void onSuccess(Latlng latlng) {
                Log.e(LOG_TAG,"siLoManager onSuccess:" + latlng);
                tvSimpleLo.setText("latlng:" + latlng.getLatitude()
                        + "\n,long:" + latlng.getLongitude()
                        + "\n,provider:" + latlng.getProvider());
                reGeManager.reGeToAddress(latlng);
            }

            @Override
            public void onFail(String msg) {
                Log.e(LOG_TAG,"error:" + msg);
                tvSimpleAd.setText("error:" + msg);
            }
        });

贴一下使用反地理编码的代码片段:

        ReverseGeocodingManager.ReGeOption reGeOption = new ReverseGeocodingManager.ReGeOption()
                .setReGeType(Constant.BAIDU_API)// 百度api返地理编码
                .setSn(true)// sn 签名校验方式
                .setIslog(true);// 打印log
        reGeManager = new ReverseGeocodingManager(this, reGeOption);
        reGeManager.addReGeListener(new IReGe.IReGeListener() {
            @Override
            public void onSuccess(int state, Latlng latlng) {
                Log.e(LOG_TAG,"reGeManager onSuccess:" + latlng);
            }

            @Override
            public void onFail(int errorCode, String error) {
                Log.e(LOG_TAG,"error:" + error);
            }
        });