android 的三种定位方式

  Android 定位大致分为三大类:GPS定位Network定位AGPS定位。而Network又细分为WIFI定位和基站定位。下面详细讲解每种定位:

  Android GPS:需要GPS硬件支持,直接和卫星交互来获取当前经纬度。

  优点:速度快、精度高、可在无网络情况下使用。

  缺点:首次连接时间长、只能在户外已经开阔地使用,设备上方有遮挡物就不行了、比较耗电。

  代码

/**
	 * 通过LocationListener来获取Location信息
	 */
	public static void formListenerGetLocation(){
		locationManager = (LocationManager)mActivity.getSystemService(Context.LOCATION_SERVICE);
		locationListener = new LocationListener() {

			@Override
			public void onLocationChanged(Location location) {
				//位置信息变化时触发
				Log4Lsy.i(TAG, "纬度:"+location.getLatitude());
				Log4Lsy.i(TAG, "经度:"+location.getLongitude());
				Log4Lsy.i(TAG, "海拔:"+location.getAltitude());
				Log4Lsy.i(TAG, "时间:"+location.getTime());
			}

			@Override
			public void onStatusChanged(String provider, int status,Bundle extras) {
				//GPS状态变化时触发
			}

			@Override
			public void onProviderEnabled(String provider) {
				//GPS禁用时触发
			}

			@Override
			public void onProviderDisabled(String provider) {
				//GPS开启时触发 
			}
		};
		/**
		 * 绑定监听
		 * 参数1,设备:有GPS_PROVIDER和NETWORK_PROVIDER两种,前者是GPS,后者是GPRS以及WIFI定位
		 * 参数2,位置信息更新周期.单位是毫秒
		 * 参数3,位置变化最小距离:当位置距离变化超过此值时,将更新位置信息
		 * 参数4,监听
		 * 备注:参数2和3,如果参数3不为0,则以参数3为准;参数3为0,则通过时间来定时更新;两者为0,则随时刷新
		 */
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
	}
   基站定位:基站定位的方式有多种,一般手机附近的三个基站进行三角定位,由于每个基站的位置是固定的,利用电磁波在这三个基站间中转所需要时间来算出手机所在的坐标,还有一种则是,利用电磁波在这三个基站间中转所需要时间来算出手机所在的坐标;第二种则是利用获取最近的基站的信息,其中包括基站 id,location area code、mobile country code、mobile network code和信号强度,将这些数据发送到google的定位web服务里,就能拿到当前所在的位置信息。

  优点:受环境的影响情况较小,不管在室内还是人烟稀少的地方都能用,只要有基站。

  缺点: 首先需要消耗流量、其实精度没有GPS那么准确,大概在十几米到几十米之间、

  代码

/**
	 * 主动获取Location,通过以下方法获取到的是最后一次定位信息。
	 * 注意:Location location=new Location(LocationManager.GPS_PROVIDER)方式获取的location的各个参数值都是为0。
	 */
	public static void getLocation(){
		locationManager = (LocationManager)mActivity.getSystemService(Context.LOCATION_SERVICE);
		Location location=locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		Log4Lsy.i(TAG, "纬度:"+location.getLatitude());
		Log4Lsy.i(TAG, "经度:"+location.getLongitude());
		Log4Lsy.i(TAG, "海拔:"+location.getAltitude());
		Log4Lsy.i(TAG, "时间:"+location.getTime());
		
	}
   WIFI定位:Wifi定位是根据一个固定的WifiMAC地址,通过收集到的该Wifi热点的位置,然后访问网络上的定位服务以获得经纬度坐标。

  优点:和基站定位一样,它的优势在于收环境影响较小,只要有Wifi的地方可以使用。

  缺点:需要有wifi、精度不准。

  代码

/**
	 * 通过WIFI获取定位信息
	 */
	public static void fromWIFILocation(){
		//WIFI的MAC地址
		WifiManager manager = (WifiManager)mActivity.getSystemService(Context.WIFI_SERVICE); 
		String wifiAddress = manager.getConnectionInfo().getBSSID(); 
		//根据WIFI信息定位
		DefaultHttpClient client = new DefaultHttpClient(); 
		HttpPost post = new HttpPost("http://www.google.com/loc/json"); 
		JSONObject holder = new JSONObject();
		try {
			holder.put("version" , "1.1.0");
			holder.put( "host" , "maps.google.com"); 
			JSONObject data;               
			JSONArray array = new JSONArray();
			if(wifiAddress!=null&&!wifiAddress.equals("")){
				data = new JSONObject(); 
				data.put("mac_address", wifiAddress); 
				data.put("signal_strength", 8); 
				data.put("age", 0); 
				array.put(data); 
			}
			holder.put("wifi_towers",array); 
			StringEntity se = new StringEntity(holder.toString()); 
			post.setEntity(se);
			HttpResponse resp =client.execute(post); 
			int state =resp.getStatusLine().getStatusCode(); 
			if (state == HttpStatus.SC_OK) {
				HttpEntity entity =resp.getEntity(); 
				if (entity != null) {
					BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
					StringBuffer sb = new StringBuffer(); 
					String resute = "";
					while ((resute =br.readLine()) != null) {                     
						sb.append(resute);                   
					}                   
					br.close(); 
					data = new JSONObject(sb.toString()); 
					data = (JSONObject)data.get("location"); 
					Location loc = new Location(LocationManager.NETWORK_PROVIDER);
					loc.setLatitude((Double)data.get("latitude"));                   
					loc.setLongitude((Double)data.get("longitude"));
					//其他信息同样获取方法
					Log4Lsy.i(TAG, "latitude ===== "+(Double)data.get("latitude"));
					Log4Lsy.i(TAG, "longitude ===== "+(Double)data.get("longitude"));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
关于WIFI定位,此处有一篇非常详尽的文章,大家可参考此文章: http://www.jb51.net/article/52673.htm
   AGPS定位:AssistedGPS(辅助全球卫星定位系统), 是结合GSM或GPRS与传统卫星定位,利用基地台代送辅助卫星信息,以缩减GPS芯片获取卫星信号的延迟时间,受遮盖的室内也能借基地台讯号弥补,减轻GPS芯片对卫星的依赖度。和纯GPS、基地台三角定位比较,AGPS能提供范围更广、更省电、速度更快的定位服务,理想误差范围在10公尺以内,日本和美国都已经成熟运用AGPS于LBS服务(Location Based Service,基于位置的服务)。AGPS技术是一种结合了网络基站信息和GPS信息对移动台进行定位的技术,可以在GSM/GPRS、WCDMA和CDMA2000网络中使进行用。该技术需要在手机内增加GPS接收机模块,并改造手机的天线,同时要在移动网络上加建位置服务器、差分GPS基准站等设备。AGPS解决方案的优势主要体现在其定位精度上,在室外等空旷地区,其精度在正常的GPS工作环境下,可以达到10米左右,堪称目前定位精度最高的一种定位技术。该技术的另一优点为:首次捕获GPS信号的时间一般仅需几秒,不像GPS的首次捕获时间可能要1分多钟,但很明显,他的硬件要求很高,造价自然高。

  代码:AGPS的定位原理和GPS原理是差不多的,所以代码其实也是用GPS的定位方式就OK了。

最后,把我写的LocationUtil类贴上。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;

import com.function.utils.Log4Lsy;

/**
 * Android API本身提供的定位功能,也是GPS定位。
 * GPS定位,是基于卫星定位。它受环境影响很大。并且是单向定位,也就是只有你自己知道你的地理坐标。
 * @author LuoSiye
 */
@TargetApi(Build.VERSION_CODES.CUPCAKE)
@SuppressLint("NewApi")
public class LocationUtil{

	private static final String TAG = "LocationUtil";
	
	private static LocationUtil instance;
	private static Activity mActivity;
	private static LocationManager locationManager;
	private static LocationListener locationListener;
	
	public static LocationUtil getInstance(Activity activity){
		mActivity = activity;
		if(instance==null){
			instance = new LocationUtil();
		}
		locationManager = (LocationManager)mActivity.getSystemService(Context.LOCATION_SERVICE);
		return instance;
	}
	
	/**
	 * 判断GPS导航是否打开.
	 * false:弹窗提示打开,不建议采用在后台强行开启的方式。
	 * true:不做任何处理
	 * @return
	 */
	public static void isOpenGPS(){
		
		if (!locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)){
			AlertDialog.Builder dialog = new AlertDialog.Builder(mActivity);
			dialog.setMessage("GPS未打开,是否打开?");
			dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
					// 设置完成后返回到原来的界面
					mActivity.startActivityForResult(intent, 0); 
				}
			});
			dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
				}
			});
			dialog.show();
		}
	}

	/**
	 * 通过LocationListener来获取Location信息
	 */
	public static void formListenerGetLocation(){
		
		locationListener = new LocationListener() {

			@Override
			public void onLocationChanged(Location location) {
				//位置信息变化时触发
				Log4Lsy.i(TAG, "纬度:"+location.getLatitude());
				Log4Lsy.i(TAG, "经度:"+location.getLongitude());
				Log4Lsy.i(TAG, "海拔:"+location.getAltitude());
				Log4Lsy.i(TAG, "时间:"+location.getTime());
			}

			@Override
			public void onStatusChanged(String provider, int status,Bundle extras) {
				//GPS状态变化时触发
			}

			@Override
			public void onProviderEnabled(String provider) {
				//GPS禁用时触发
			}

			@Override
			public void onProviderDisabled(String provider) {
				//GPS开启时触发 
			}
		};
		/**
		 * 绑定监听
		 * 参数1,设备:有GPS_PROVIDER和NETWORK_PROVIDER两种,前者是GPS,后者是GPRS以及WIFI定位
		 * 参数2,位置信息更新周期.单位是毫秒
		 * 参数3,位置变化最小距离:当位置距离变化超过此值时,将更新位置信息
		 * 参数4,监听
		 * 备注:参数2和3,如果参数3不为0,则以参数3为准;参数3为0,则通过时间来定时更新;两者为0,则随时刷新
		 */
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
	}
	
	/**
	 * 主动获取Location,通过以下方法获取到的是最后一次定位信息。
	 * 注意:Location location=new Location(LocationManager.GPS_PROVIDER)方式获取的location的各个参数值都是为0。
	 */
	public static void getLocation(){
		
		Location location=locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		Log4Lsy.i(TAG, "纬度:"+location.getLatitude());
		Log4Lsy.i(TAG, "经度:"+location.getLongitude());
		Log4Lsy.i(TAG, "海拔:"+location.getAltitude());
		Log4Lsy.i(TAG, "时间:"+location.getTime());
		
	}
	
	/**
	 * 获取GPS状态监听,包括GPS启动、停止、第一次定位、卫星变化等事件。
	 */
	public static void getStatusListener(){
		
		GpsStatus.Listener listener = new GpsStatus.Listener(){

			@Override
			public void onGpsStatusChanged(int event) {
				if(event==GpsStatus.GPS_EVENT_FIRST_FIX){
					//第一次定位
				}else if(event==GpsStatus.GPS_EVENT_SATELLITE_STATUS){
					//卫星状态改变
					GpsStatus gpsStauts= locationManager.getGpsStatus(null); // 取当前状态
					int maxSatellites = gpsStauts.getMaxSatellites(); //获取卫星颗数的默认最大值
					Iterator<GpsSatellite> it = gpsStauts.getSatellites().iterator();//创建一个迭代器保存所有卫星
					int count = 0;
					while (it.hasNext() && count <= maxSatellites) {    
		                count++;   
		                GpsSatellite s = it.next();  
		            }
					Log4Lsy.i(TAG, "搜索到:"+count+"颗卫星");
				}else if(event==GpsStatus.GPS_EVENT_STARTED){
					//定位启动
				}else if(event==GpsStatus.GPS_EVENT_STOPPED){
					//定位结束
				}
			}
		};
		//绑定
		locationManager.addGpsStatusListener(listener); 
	}
	
	/**
	 * 获取所有卫星状态
	 * @return
	 */
	public static List<GpsSatellite> getGpsStatus(){
		List<GpsSatellite> result = new ArrayList<GpsSatellite>();
		GpsStatus gpsStatus = locationManager.getGpsStatus(null); // 取当前状态
		//获取默认最大卫星数
		int maxSatellites = gpsStatus.getMaxSatellites();
		//获取第一次定位时间(启动到第一次定位)
		int costTime=gpsStatus.getTimeToFirstFix();
		Log4Lsy.i(TAG, "第一次定位时间:"+costTime);
		//获取卫星
		Iterable<GpsSatellite> iterable=gpsStatus.getSatellites();
		//一般再次转换成Iterator
		Iterator<GpsSatellite> itrator=iterable.iterator();
		int count = 0;
		while (itrator.hasNext() && count <= maxSatellites){
			count++;
			GpsSatellite s = itrator.next();
			result.add(s);
		}
		return result;
	}
	
	/**
	 * 某一个卫星的信息.
	 * @param gpssatellite
	 */
	public static void getGpsStatelliteInfo(GpsSatellite gpssatellite){
		
		//卫星的方位角,浮点型数据  
		Log4Lsy.i(TAG, "卫星的方位角:"+gpssatellite.getAzimuth());
	    //卫星的高度,浮点型数据  
		Log4Lsy.i(TAG, "卫星的高度:"+gpssatellite.getElevation());
	    //卫星的伪随机噪声码,整形数据  
		Log4Lsy.i(TAG, "卫星的伪随机噪声码:"+gpssatellite.getPrn());
	    //卫星的信噪比,浮点型数据  
		Log4Lsy.i(TAG, "卫星的信噪比:"+gpssatellite.getSnr());
	    //卫星是否有年历表,布尔型数据  
		Log4Lsy.i(TAG, "卫星是否有年历表:"+gpssatellite.hasAlmanac());
	    //卫星是否有星历表,布尔型数据  
		Log4Lsy.i(TAG, "卫星是否有星历表:"+gpssatellite.hasEphemeris());
	    //卫星是否被用于近期的GPS修正计算  
		Log4Lsy.i(TAG, "卫星是否被用于近期的GPS修正计算:"+gpssatellite.hasAlmanac());
	}
	
	/**
	 * 通过WIFI获取定位信息
	 */
	public static void fromWIFILocation(){
		//WIFI的MAC地址
		WifiManager manager = (WifiManager)mActivity.getSystemService(Context.WIFI_SERVICE); 
		String wifiAddress = manager.getConnectionInfo().getBSSID(); 
		//根据WIFI信息定位
		DefaultHttpClient client = new DefaultHttpClient(); 
		HttpPost post = new HttpPost("http://www.google.com/loc/json"); 
		JSONObject holder = new JSONObject();
		try {
			holder.put("version" , "1.1.0");
			holder.put( "host" , "maps.google.com"); 
			JSONObject data;               
			JSONArray array = new JSONArray();
			if(wifiAddress!=null&&!wifiAddress.equals("")){
				data = new JSONObject(); 
				data.put("mac_address", wifiAddress); 
				data.put("signal_strength", 8); 
				data.put("age", 0); 
				array.put(data); 
			}
			holder.put("wifi_towers",array); 
			StringEntity se = new StringEntity(holder.toString()); 
			post.setEntity(se);
			HttpResponse resp =client.execute(post); 
			int state =resp.getStatusLine().getStatusCode(); 
			if (state == HttpStatus.SC_OK) {
				HttpEntity entity =resp.getEntity(); 
				if (entity != null) {
					BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
					StringBuffer sb = new StringBuffer(); 
					String resute = "";
					while ((resute =br.readLine()) != null) {                     
						sb.append(resute);                   
					}                   
					br.close(); 
					data = new JSONObject(sb.toString()); 
					data = (JSONObject)data.get("location"); 
					Location loc = new Location(LocationManager.NETWORK_PROVIDER);
					loc.setLatitude((Double)data.get("latitude"));                   
					loc.setLongitude((Double)data.get("longitude"));
					//其他信息同样获取方法
					Log4Lsy.i(TAG, "latitude ===== "+(Double)data.get("latitude"));
					Log4Lsy.i(TAG, "longitude ===== "+(Double)data.get("longitude"));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

第一篇博文,写的有点简单,欢迎各位斧正,下篇写一下如何集成百度、高德、腾讯的地图到有应用中~






  • 12
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值