最近应为工作需要,要做定位的功能

在定位的功能实现中首先我们需要获取到系统的LocationManager,获取方式为

// 获取系统定位管理
        String context = Context.LOCATION_SERVICE;
        locationManager = (LocationManager) getSystemService(context);

然后可以设置Criteria:

        // 设置Criteria(服务商)的信息
        Criteria criteria = new Criteria();
        // 经度要求
        // criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setAltitudeRequired(false);
        criteria.setBearingRequired(false);
        criteria.setCostAllowed(false);
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        // 取得最好效果的criteria
        String provider = locationManager.getBestProvider(criteria, true);


这个时候就可以获得相应的坐标信息了:

// 获得坐标相应信息
        Location location = locationManager.getLastKnownLocation(provider);

当然我们还可以设置监听事件:

//设置监听
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,500, 20,locationListener);

参考信息

由于人的位置是不断变化,我要设置一个位置变化的范围,包括同时满足最小的时间间隔和最小的位移变化,如果两个条件要同时满足,将位置监听器将被触发。实际上该方法有多个参数格式,特别是requestLocationUpdates (long minTime, float minDistance, Criteria criteria,PendingIntent intent),当位置变化时可调用其他的Activity。 在本例中,我们制定用GPS,则在权限中必须要求精确定位许可。
        mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000/*10秒,为测试方便*/, 1000/*1公里*/, onLocationChange/*位置监听器*/);



监听事件:


// 提供定位信息发生改变时的回调。必须事先在定位管理器中注册监听器对象。
    private LocationListener locationListener = new LocationListener() {
        // Provider的转态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO Auto-generated method stub

        }

        // Provider启用时触发此函数,比如GPS被打开。
        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub

        }

        // Provider禁用时触发此函数,比如GPS被关闭。
        @Override
        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub
            

        }

        // 当坐标改变时候触发该函数,如果Provider传相同的坐标,它就不会触发。
        @Override
        public void onLocationChanged(Location location) {
            // TODO Auto-generated method stub
            if (location != null) {
                // 为绘制标志的类设置坐标
                // myPosition.
                // 取得经度和纬度
                Double geoLat = location.getLatitude() * 1E6;
                Double geoLng = location.getLongitude() * 1E6;

                Log.i("latitudetag", Double.toString(geoLat));

                Log.i("latitudetag", Double.toString(geoLng));
                edittext.setText(Double.toString(geoLat) + "," + Double.toString(geoLng));
            }

        }
    };


之前一直不知道饿了么这种送餐平台为什么定位需要开启wifi现在也有些了解:

参考知乎上面的回答:


1.每一个无线AP都有一个全球唯一的MAC地址,并且一般来说无线AP在一段时间内是不会移动的
2.设备在开启Wi-Fi的情况下,即可扫描并收集周围的AP信号,无论是否加密,是否已连接,甚至信号强度不足以显示在无线信号列表中,都可以获取到AP广播出来的MAC地址

3.设备将这些能够标示AP的数据发送到位置服务器,服务器检索出每一个AP的地理位置,并结合每个信号的强弱程度,计算出设备的地理位置并返回到用户设备



其中步骤有:


1、AP的信号中包含全球唯一的MAC地址。
2、只要能够搜索到wifi信号,就能得知AP的MAC地址,并不需要连接到wifi。
3、每一个AP在地理坐标上作为一个锚点,并且用MAC地址来唯一标识它。
4、wifi定位是通过参照一个或多个AP的坐标计算得出来的。
5、在服务器端维护了一个AP的坐标数据库。
6、AP的位置(坐标)是通过参照连网的GPS设备得到,GPS设备定位成功后GPS应用自动将其周边的AP信息反馈给服务器,自动维护AP坐标数据库。
7、通过wifi定位时,GPS应用通过周边AP信号的MAC地址去查询每个AP的坐标,并根据信号的强度计算出所在的位置。