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 = -0L; 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; } }
今天的文章
Android中获取当前位置的三种方式分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/4645.html