GL_BOOK_10

本文介绍LBS基于位置的服务实现原理及应用,详细讲解了LocationManager的使用方法,包括获取位置信息、更新位置监听等,并提供了反向地理编码的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CHAPTER 10
LBS 基于位置服务
LocationManager
getSystemService(Context.LOCATION_SERVICE);
由三种位置提供器来确定设备当前位置
分别是 GPS_PROVIDER , NETWORK_PROVIDER , PASSIVE_PROVIDER
尤其前两种方式使用较多
第一种GPS 定位比较精确但耗电较多
第二种网络定位相对耗电较少但不够精确
定位功能必须由用户主动启用才行
将选择好的位置提供器传入到getLastKnownLocation()方法中 ,就可以得到一个Location对象
String provider = LocationManager.NETWORK_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
需要权限

 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

此时该location中包含 经度(longitude) 、 纬度(latitude) 、 海拔(altitude) 等一系列的位置信息 。
如果有时候想让定位的精度更高一些,但又不确定 GPS 定位的功能是否启用 ,这个时候可以先判断有哪些位置提供器可用

List<String> providerList = locationManager.getProviders(true);

传入 true 就表示只有启用的位置提供器才会被返回。之后在 List 中进行判断是否包含 GPS 定位的功能即可

调用 getLastKnownLocation() 虽可以获取设备当前位置 ,但是用户完全有可能带着设备随时移动,如果在设备位置发生变化时获取到最新的位置信息呢?
LocationManager 提供了 requestLocationUpdate() 方法,只要传入一个 LocationListener 的实例,并简单配置几个参数即可实现

android.location.LocationManager.requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)

Parameters:
provider the name of the provider with which to register
minTime minimum time interval between location updates, in milliseconds
minDistance minimum distance between location updates, in meters
listener a LocationListener whose LocationListener.onLocationChanged method will be called for each location update

移除监听
void android.location.LocationManager.removeUpdates(LocationListener listener)

locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        List<String> providerList = locationManager.getProviders(true);

        if (providerList.contains(LocationManager.GPS_PROVIDER)) {
            provider = LocationManager.GPS_PROVIDER;
        }else if (providerList.contains(LocationManager.NETWORK_PROVIDER)) {
            provider = LocationManager.NETWORK_PROVIDER;
        }else if (providerList.contains(LocationManager.PASSIVE_PROVIDER)) {
            provider = LocationManager.PASSIVE_PROVIDER;
        }else {
            Toast.makeText(this, "No location provider to use", Toast.LENGTH_SHORT).show();
            return ;
        }
        mLocation = locationManager.getLastKnownLocation(provider);
        showLocationInfo(mLocation);
        locationManager.requestLocationUpdates(provider, 5000, 1, listener);
private void showLocationInfo(Location location) {
        double latitude =location.getLatitude();//纬度
        double longitude = location.getLongitude();//经度
        double altitude = location.getAltitude();//海拔
        String locationInfo = "所在位置\n纬度 : "+latitude+"\n经度 : "+longitude+"\n海拔 : "+altitude;
        tv.setText(locationInfo);
    }
private LocationListener listener = new LocationListener() {

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onLocationChanged(Location location) {
            Toast.makeText(LocationActivity.this, "reLocating ---", Toast.LENGTH_SHORT).show();
            mLocation = location;
            showLocationInfo(location);
        }
    };
@Override
    protected void onDestroy() {
        super.onDestroy();
        if (locationManager!=null) {
            locationManager.removeUpdates(listener);
        }
    }

反向地理编码 将经纬度转化成看的懂的地理信息
google 提供给了相对稳定的Geocoding API
其中反向地理编码的接口如下

http://maps.googleapis.com/maps/api/geocode/json?latlng=xxx,xxx&sensor = false

固定不变的连接地址
http://maps.googleapis.com/api/geocode/
json 表示希望服务器返回的数据格式是 JSON格式 ,这里也可以用xml
latlng = xxx,xxx 纬度,经度
sensor 表示这条请求是否来自某个设备的位置传感器,通常置为false 即可
返回的数据 json格式的话 我们需要的信息 一个是 results 对应的 jsonarray
一个是 jsonarr中的 jsonobject 中 地理位置信息对应的key formatted_address

private void geocodeLocation(final Location location){
        new Thread(new Runnable() {

            @Override
            public void run() {
                StringBuilder url = new StringBuilder();
                url.append("http://maps.googleapis.com/maps/api/geocode/json?latlng=");
                url.append(location.getLatitude()+","+location.getLongitude())
                .append("&sensor=false");
                HttpClient client  = new DefaultHttpClient();
                HttpGet get  = new HttpGet(url.toString());
                Log.i("haha", url.toString());

                get.addHeader("Accept-Language", "zh-CN");
                HttpResponse response;
                try {
                    response = client.execute(get);
                    if (response.getStatusLine().getStatusCode()==200) {
                        Log.i("haha", "请求成功  状态码 200");

                        HttpEntity entity  = response.getEntity();
                        String result = EntityUtils.toString(entity,"utf-8");
                        JSONObject jsonObject = new JSONObject(result);
                        JSONArray arr  = jsonObject.getJSONArray("results");
                        if (arr.length()>0) {
                            Log.i("haha", "请求成功  有数据 arr.length : "+arr.length());
                            JSONObject object = arr.getJSONObject(0);
                            addressInfo= object.getString("formatted_address");
                            runOnUiThread(new Runnable() {

                                @Override
                                public void run() {
                                    tv.setText(addressInfo);
                                }
                            });
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }).start();
    }

以上代码都是学习内容 实际情况时 有时 Location 会为空 即使 GPS 和 网络都是打开的情况下
stackoverflow 上 有解决的方案 地址链接 Location null 如何解决 点击查看

private void getBestValidLocation(){
        Location bestLocation = null;
        List<String> providers = locationManager.getProviders(true);
        for (String provide : providers) {
            Location l = locationManager.getLastKnownLocation(provide);
            if (l==null) {
                continue;
            }
            if (bestLocation==null||bestLocation.getAccuracy()<l.getAccuracy()) {
                bestLocation = l;
                mProvider = provide;
            }
        }
        mLocation  = bestLocation;
    }

百度地图的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值