Android中获取当前位置的三种方式

1.GPS定位

  在实现GPS定位前,先了解一下GPS的部分特性:

  1. GPS定位需要依靠3颗或3颗以上的卫星。

  2. GPS定位受环境影响较大,在晴朗的空地上,较容易搜索到卫星,而在室内通常是无法搜索到卫星的。

  3. GPS定位需要使用GPS功能模块,而GPS功能模块的耗电量是巨大的。

  在Android系统中,实现GPS定位的思路应该是:

  1. 获取GPS的Location Provider。

  2. 讲此Provider传入到requestLocationUpdates()方法,让Android系统获知搜索位置方式。

  3. 创建实现了GpsStatus.Listener接口的对象,重写onGpsStatusChanged()方法,向LocationManager添加次监听器,检测卫星状态。(可选步骤)

  根据以上思路,仿照Android定位功能(一)中的例子,可以很容易的得到以下实现代码:

 

public class MainActivity extends Activity {
 private LocationManager locationManager;
 private GpsStatus gpsstatus;
@Override
 public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//获取到LocationManager对象
 locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

//根据设置的Criteria对象,获取最符合此标准的provider对象
 String currentProvider = locationManager.getProvider(LocationManager.GPS_PROVIDER).getName();

//根据当前provider对象获取最后一次位置信息
 Location currentLocation = locationManager.getLastKnownLocation(currentProvider);
//如果位置信息为null,则请求更新位置信息
 if(currentLocation == null){
 locationManager.requestLocationUpdates(currentProvider, 0, 0, locationListener);
}
//增加GPS状态监听器
locationManager.addGpsStatusListener(gpsListener);

//直到获得最后一次位置信息为止,如果未获得最后一次位置信息,则显示默认经纬度
//每隔10秒获取一次位置信息
while(true){
 currentLocation = locationManager.getLastKnownLocation(currentProvider);
 if(currentLocation != null){
 Log.d("Location","Latitude:"+ currentLocation.getLatitude());
 Log.d("Location","location:"+ currentLocation.getLongitude());
break;
}else{
 Log.d("Location","Latitude:"+ 0);
 Log.d("Location","location:"+ 0);
}
 try {
Thread.sleep(10000);
 } catch (InterruptedException e) {
 Log.e("Location", e.getMessage());
}
}
}

 private GpsStatus.Listener gpsListener = new GpsStatus.Listener(){
//GPS状态发生变化时触发
@Override
 public void onGpsStatusChanged(int event) {
//获取当前状态
gpsstatus=locationManager.getGpsStatus(null);
switch(event){
//第一次定位时的事件
 case GpsStatus.GPS_EVENT_FIRST_FIX:
break;
//开始定位的事件
 case GpsStatus.GPS_EVENT_STARTED:
break;
//发送GPS卫星状态事件
 case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
 Toast.makeText(MainActivity.this,"GPS_EVENT_SATELLITE_STATUS", Toast.LENGTH_SHORT).show();
 Iterable<GpsSatellite> allSatellites = gpsstatus.getSatellites(); 
 Iterator<GpsSatellite> it=allSatellites.iterator(); 
 int count = 0;
while(it.hasNext())
{
count++;
}
 Toast.makeText(MainActivity.this,"Satellite Count:"+ count, Toast.LENGTH_SHORT).show();
break;
//停止定位事件
 case GpsStatus.GPS_EVENT_STOPPED:
 Log.d("Location","GPS_EVENT_STOPPED");
break;
}
}
};


//创建位置监听器
 private LocationListener locationListener = new LocationListener(){
//位置发生改变时调用
@Override
 public void onLocationChanged(Location location) {
 Log.d("Location","onLocationChanged");
}

//provider失效时调用
@Override
 public void onProviderDisabled(String provider) {
 Log.d("Location","onProviderDisabled");
}

//provider启用时调用
@Override
 public void onProviderEnabled(String provider) {
 Log.d("Location","onProviderEnabled");
}

//状态改变时调用
@Override
 public void onStatusChanged(String provider, int status, Bundle extras) {
 Log.d("Location","onStatusChanged");
}
};
}

 

 2.基站定位

    此类位置的获取有赖于手机无线通讯信号,当手机处在信号覆盖范围内,手机可以获得该区域(即通讯术语中的“小区”)的识别号。因为这些识别号是惟一的,因此可以将识别号和地理坐标对应起来,因此根据识别号就可以知道地理位置。但是误差比较大。

   MCC(Mobile Country Code)、MNC(Mobile Network Code)、LAC(Location Aera Code)、CID(Cell Tower ID)是通讯业内的名词。MCC标识国家,MNC标识网络,两者组合起来则唯一标识一家通讯运营商。从维基百科上了解到,一个国家的MCC不唯一,例如中国有460和461,一家运营商也不只一个MNC,例如中国移动有00、02、07。LAC标识区域,类似于行政区域,运营商将大区域划分成若干小区域,每个区域分配一个LAC。CID标识基站,若手机处在工作状态,则必须要和一个通讯基站进行通讯,通过CID就可以确定手机所在的地理范围。

   在Android当中,大部分和通讯网络相关的信息都需要经过一项系统服务,即TelephoneManager来获得。

 

/**
 * Google定位的实现.<br/> 
 * Geolocation的详细信息请参见:<br/> 
 * <a 
 * href="http://code.google.com/apis/gears/geolocation_network_protocol.html"mce_href="http://code.google.com/apis/gears/geolocation_network_protocol.html"> 
 * http://code.google.com/apis/gears/geolocation_network_protocol.html</a> 
*/
public class LocationAct extends Activity { 
 private TextView txtInfo; 
 public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
 Button btn = (Button) findViewById(R.id.btnStart); 
 txtInfo = (TextView) findViewById(R.id.txtInfo); 
 btn.setOnClickListener(new Button.OnClickListener() { 
 public void onClick(View view) { 
getLocation();
}
});
}
 private void getLocation() { 
 TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
 GsmCellLocation gsmCell = (GsmCellLocation) tm.getCellLocation(); 
 int cid = gsmCell.getCid(); 
 int lac = gsmCell.getLac(); 
 String netOperator = tm.getNetworkOperator(); 
 int mcc = Integer.valueOf(netOperator.substring(0, 3)); 
 int mnc = Integer.valueOf(netOperator.substring(3, 5)); 
 JSONObject holder = new JSONObject(); 
 JSONArray array = new JSONArray(); 
 JSONObject data = new JSONObject(); 
 try { 
 holder.put("version","1.1.0"); 
 holder.put("host","maps.google.com"); 
 holder.put("address_language","zh_CN"); 
 holder.put("request_address", true); 
 holder.put("radio_type","gsm"); 
 holder.put("carrier","HTC"); 
 data.put("cell_id", cid); 
 data.put("location_area_code", lac); 
 data.put("mobile_countyr_code", mcc); 
 data.put("mobile_network_code", mnc); 
array.put(data);
 holder.put("cell_towers", array); 
 } catch (JSONException e) { 
e.printStackTrace();
}
 DefaultHttpClient client = new DefaultHttpClient(); 
 HttpPost httpPost = new HttpPost("http://www.google.com/loc/json"); 
 StringEntity stringEntity = null; 
 try { 
 stringEntity = new StringEntity(holder.toString()); 
 } catch (UnsupportedEncodingException e) { 
e.printStackTrace();
}
httpPost.setEntity(stringEntity);
 HttpResponse httpResponse = null; 
 try { 
 httpResponse = client.execute(httpPost); 
 } catch (ClientProtocolException e) { 
e.printStackTrace();
 } catch (IOException e) { 
e.printStackTrace();
}
 HttpEntity httpEntity = httpResponse.getEntity(); 
 InputStream is = null; 
 try { 
 is = httpEntity.getContent(); 
 } catch (IllegalStateException e) { 
e.printStackTrace();
 } catch (IOException e) { 
 // TODO Auto-generated catch block 
e.printStackTrace();
}
 InputStreamReader isr = new InputStreamReader(is); 
 BufferedReader reader = new BufferedReader(isr); 
 StringBuffer stringBuffer = new StringBuffer(); 
 try { 
 String result =""; 
 while ((result = reader.readLine()) != null) { 
stringBuffer.append(result);
}
 } catch (IOException e) { 
e.printStackTrace();
}
txtInfo.setText(stringBuffer.toString());
}
}

 3.网络定位(wife定位)

 其原理是首先收集每个WIFI无线接入点的位置,对每个无线路由器进行唯一的标识,在数据库中注明这些接入点的具体位置。 使用时,一旦发现有WI-FI接入点,则进入到数据中查看匹配的记录,进而得到位置信息。

  WIFI定位主要取决于节点(node)的物理地址(mac address)。与提供TelephoneManager一样,Android也提供了获取WIFI信息的接口:WifiManager。

public class WiFiInfoManager implements Serializable { 
 private static final long serialVersionUID = -4582739827003032383L; 

 private Context context; 

 public WiFiInfoManager(Context context) { 
super();
 this.context = context; 
}

 public WifiInfo getWifiInfo() { 
 WifiManager manager = (WifiManager) context 
.getSystemService(Context.WIFI_SERVICE);
 WifiInfo info = new WifiInfo(); 
 info.mac = manager.getConnectionInfo().getBSSID(); 
 Log.i("TAG","WIFI MAC is:"+ info.mac); 
 return info; 
}

 public class WifiInfo { 

 public String mac; 

 public WifiInfo() { 
super();
}
}

}

//上面是取到WIFI的mac地址的方法,下面是把地址发送给google服务器,代码如下:

public static Location getWIFILocation(WifiInfo wifi) { 

 if (wifi == null) { 

 Log.i("TAG","wifi is null."); 

 return null; 

}

 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 (wifi.mac != null && wifi.mac.trim().length() > 0) { 

 data = new JSONObject(); 

 data.put("mac_address", wifi.mac); 

 data.put("signal_strength", 8); 

 data.put("age", 0); 

array.put(data);

}

 holder.put("wifi_towers", array); 

 Log.i("TAG","request json:"+ holder.toString()); 

 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();



 Log.i("TAG","response json:"+ sb.toString()); 

 data = new JSONObject(sb.toString()); 

 data = (JSONObject) data.get("location"); 



 Location loc = new Location( 

android.location.LocationManager.NETWORK_PROVIDER);

 loc.setLatitude((Double) data.get("latitude")); 

 loc.setLongitude((Double) data.get("longitude")); 

loc.setAccuracy(Float.parseFloat(data.get("accuracy")

.toString()));

loc.setTime(System.currentTimeMillis());

 return loc; 

 } else { 

 return null; 

}

 } else { 

 Log.v("TAG", state +""); 

 return null; 

}



 } catch (Exception e) { 

 Log.e("TAG", e.getMessage()); 

 return null; 

}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值