android知识小贴士之二:基于位置的服务

[TOC]
android基于位置的服务(Location Based Service)简称LBS,
它是通过无线电通讯网络(如GMS网或CMDA网)或外部定位方式(如GPS)来确定移动终端的位置。
GPS的定位精确度较高,但耗电量高,更新用户位置也比较慢,且只能在户外使用;而网络定位户外户内都可以使用,耗电量少,且更新速度快。

基础知识(主要的类及方法)

  1. LocationManager:此类提供对系统定位服务的访问。除非说明,否则所有的位置访问都需要权限ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION.
    1.1 List’<’String’>’ getAllProviders():返回所有已知位置提供者的名字;
    1.2 Location getLastKnownLocation(String Provider):返回一个Location,包含从位置提供者获得的数据;
    1.3 void requestLocationUpdates(String providers,long minTime,long minDistance,LocationListener listener):每隔minTime毫秒,并移动了minDistance米更新位置信息。
  2. LocationProvider:位置提供者的抽像超类。定期的返回所在位置的信息。不同的位置提供程序有不同的实现条件,比如有些提供者程序需要GPS硬件和对大量卫星可见;有些需要蜂窝网;有些需要联入一个特定的载体网络或互联网。
    2.1 int getAccuracy():返回提供者的水平精度常数。
    2.2 String getName(): 返回提供者的名字。
  3. Location:表示一个地理位置的类。它包括位置的经度,纬度和其他信息如,方位,高度,速度。
    3.1 float getAccuracy():获取位置信息,精度为米。
    3.2 double getAltitude():获取位置的高度。
    3.3 Bundle getExtra():

代码示例

使用GeoCoding API进行反向地理编码,先向服务器发送一个http请求,然后对返回的JSON数据进行解析。发送http请求用HttpClient,JSON数据处理用JSONObject。

package com.example.geocoderdemo;

import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends Activity {
    protected static final int SHOW_LOCATION = 0;
    public LocationManager lm;
    public TextView tv1;
    @Override//1.主方法
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv1=(TextView)findViewById(R.id.tv1);
        //获取所有的位置提供器
        String provider;
        LocationManager lm=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
        List<String> providers=lm.getAllProviders();
        if(providers.contains(LocationManager.NETWORK_PROVIDER))
            provider=LocationManager.NETWORK_PROVIDER;
        else if(providers.contains(LocationManager.GPS_PROVIDER))
            provider=LocationManager.GPS_PROVIDER;
        //没有提供器则提示
        else{
            Toast.makeText(MainActivity.this, "没有提供器", Toast.LENGTH_SHORT).show();
        return; 
        }
        Location location=lm.getLastKnownLocation(provider);
        if(location!=null){
            showLocation(location);
        }
        lm.requestLocationUpdates(provider, 5000, 1, listener);
    }
    //2.销毁
    public void onDestroy(){
        super.onDestroy();
        if(lm!=null)
            lm.removeUpdates(listener);

    }
    //4.给location注册监听器
    LocationListener listener=new LocationListener(){

        @Override
        public void onLocationChanged(Location arg0) {
            // TODO Auto-generated method stub

        }

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

        }

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

        }

        @Override
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
            // TODO Auto-generated method stub

        }

    };


    //3.showLocation()方法
    public void showLocation(final Location location){
        new Thread(new Runnable(){

            private int SHOW_LOCATION;

            @Override
            public void run() {
                try{
                //组装反向的编码接口地址
                StringBuilder url=new StringBuilder();
                url.append("http://maps.googleapis.com/maps/api/geocode/json?latlng=");
                url.append(location.getLatitude());
                url.append(",");
                url.append(location.getLongitude());
                url.append("&sensor=false");
                HttpClient httpClient=new DefaultHttpClient();//创建客户端对象
                HttpGet httpGet=new HttpGet(url.toString());
                //在请求消息头中指定语言,保证服务器会返回中文数据 
                 httpGet.addHeader("Accept-Language", "zh-CN");  
                 HttpResponse httpResponse = httpClient.execute(httpGet);  
                 if (httpResponse.getStatusLine().getStatusCode() == 200) {  
                     HttpEntity entity = httpResponse.getEntity();  
                     String response = EntityUtils.toString(entity, "utf-8");  
                     JSONObject jsonObject = new JSONObject(response);
                // 获取results节点下getS的位置信息
                     JSONArray resultArray = jsonObject.getJSONArray("results");  
                     if (resultArray.length() > 0) {  
                         JSONObject subObject = resultArray.getJSONObject(0);
                // 取出格式化后的位置信息
                         String address = subObject.getString("formatted_address");  
                         Message message = new Message();  
                         message.what = SHOW_LOCATION;  
                         message.obj = address;  
                         handler.sendMessage(message);  
                     }  
                 }  
             } catch (Exception e) {  
                 e.printStackTrace();  
             }  
         }  
     }).start();  
 }
     private Handler handler = new Handler() {  

            public void handleMessage(Message msg) {  
                switch (msg.what) {  
                case SHOW_LOCATION:  
                    String currentPosition = (String) msg.obj; 
                    tv1.setText(currentPosition);  
                    break;  
                default:  
                    break;  
                }  
            }  

        };  
}