不过其实只要明白了基站/WIFI定位的原理,自己实现基站/WIFI定位其实不难。基站定位一般有几种,第一种是利用手机附近的三个基站进行三角定位,由于每个基站的位置是固定的,利用电磁波在这三个基站间中转所需要时间来算出手机所在的坐标;第二种则是利用获取最近的基站的信息,其中包括基站id,location area code、mobile country code、mobile network code和信号强度,将这些数据发送到google的定位web服务里,就能拿到当前所在的位置信息,误差一般在几十米到几百米之内。其中信号强度这个数据很重要,网上很多所谓的手动通过基站和WIFI信息定位的方法误差大都是因为没使用信号强度而导致误差过大。高德也自己做了一个基站库,具体可以google搜索一下。
现在在一些大中型城市里,WIFI已经普及,有私人或企业的WIFI,亦有中国电信的WIFI,通过WIFI信息进行定位,并不需要真正连接上指定的WIFI路由器,只需要探测到有WIFI存在即可,因此当手机使用的不是GSM制式(因为google的基站库里并没在保存太多的CDMA基站)的时候,也可以使用WIFI进行定位,原理也和基站定位一样,必须要拿到WIFI路由器的SSID和信号强度。
由于有些用户默认是将WIFI关闭的,通过API开启WIFI硬件并进行搜索附近的WIFI路由器需要一段时间,怎样才能将手机基站定位和WIFI定位完美结合起来呢,Android提供了一种很好的机制,就是Handler和Looper,Handler和Looper一般用于跨线程传递数据,但当在单线程里使用时,就变成了一个先进先出的消息泵。利用这个消息泵进行调度,就可以将基站定位和WIFI定位完美结合。以下是相关的代码:
CellInfoManager
import java.lang.reflect.Method;import java.util.Iterator;import java.util.List;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import android.content.Context;import android.telephony.CellLocation;import android.telephony.NeighboringCellInfo;import android.telephony.PhoneStateListener;import android.telephony.TelephonyManager;import android.telephony.gsm.GsmCellLocation;import android.util.Log;public class CellInfoManager {private int asu;private int bid;private int cid;private boolean isCdma;private boolean isGsm;private int lac;private int lat;private final PhoneStateListener listener;private int lng;private int mcc;private int mnc;private int nid;private int sid;private TelephonyManager tel;private boolean valid;private Context context;public CellInfoManager(Context paramContext) { this.listener = new CellInfoListener(this); tel = (TelephonyManager) paramContext.getSystemService(Context.TELEPHONY_SERVICE); this.tel.listen(this.listener, PhoneStateListener.LISTEN_CELL_LOCATION | PhoneStateListener.LISTEN_SIGNAL_STRENGTH); context = paramContext;}public static int dBm(int i) { int j; if (i >= 0 && i <= 31) j = i * 2 + -113; else j = 0; return j;}public int asu() { return this.asu;}public int bid() { if (!this.valid) update(); return this.bid;}public JSONObject cdmaInfo() { if (!isCdma()) { return null; } JSONObject jsonObject = new JSONObject(); try { jsonObject.put("bid", bid()); jsonObject.put("sid", sid()); jsonObject.put("nid", nid()); jsonObject.put("lat", lat()); jsonObject.put("lng", lng()); } catch (JSONException ex) { jsonObject = null; Log.e("CellInfoManager", ex.getMessage()); } return jsonObject;}public JSONArray cellTowers() { JSONArray jsonarray = new JSONArray(); int lat; int mcc; int mnc; int aryCell[] = dumpCells(); lat = lac(); mcc = mcc(); mnc = mnc(); if (aryCell == null || aryCell.length < 2) { aryCell = new int[2]; aryCell[0] = cid; aryCell[1] = -60; } for (int i = 0; i < aryCell.length; i += 2) { try {int j2 = dBm(i + 1);JSONObject jsonobject = new JSONObject();jsonobject.put("cell_id", aryCell[i]);jsonobject.put("location_area_code", lat);jsonobject.put("mobile_country_code", mcc);jsonobject.put("mobile_network_code", mnc);jsonobject.put("signal_strength", j2);jsonobject.put("age", 0);jsonarray.put(jsonobject); } catch (Exception ex) {ex.printStackTrace();Log.e("CellInfoManager", ex.getMessage()); } } if (isCdma()) jsonarray = new JSONArray(); return jsonarray;}public int cid() { if (!this.valid) update(); return this.cid;}public int[] dumpCells() { int[] aryCells; if (cid() == 0) { aryCells = new int[0]; return aryCells; } List<NeighboringCellInfo> lsCellInfo = this.tel.getNeighboringCellInfo(); if (lsCellInfo == null || lsCellInfo.size() == 0) { aryCells = new int[1]; int i = cid(); aryCells[0] = i; return aryCells; } int[] arrayOfInt1 = new int[lsCellInfo.size() * 2 + 2]; int j = 0 + 1; int k = cid(); arrayOfInt1[0] = k; int m = j + 1; int n = asu(); arrayOfInt1[j] = n; Iterator<NeighboringCellInfo> iter = lsCellInfo.iterator(); while (true) { if (!iter.hasNext()) {break; } NeighboringCellInfo localNeighboringCellInfo = (NeighboringCellInfo) iter.next(); int i2 = localNeighboringCellInfo.getCid(); if ((i2 <= 0) || (i2 == 65535))continue; int i3 = m + 1; arrayOfInt1[m] = i2; m = i3 + 1; int i4 = localNeighboringCellInfo.getRssi(); arrayOfInt1[i3] = i4; } int[] arrayOfInt2 = new int[m]; System.arraycopy(arrayOfInt1, 0, arrayOfInt2, 0, m); aryCells = arrayOfInt2; return aryCells;}public JSONObject gsmInfo() { if (!isGsm()) { return null; } JSONObject localObject = null; while (true) { try {JSONObject localJSONObject1 = new JSONObject();String str1 = this.tel.getNetworkOperatorName();localJSONObject1.put("operator", str1);String str2 = this.tel.getNetworkOperator();if ((str2.length() == 5) || (str2.length() == 6)) {String str3 = str2.substring(0, 3);String str4 = str2.substring(3, str2.length());localJSONObject1.put("mcc", str3);localJSONObject1.put("mnc", str4);}localJSONObject1.put("lac", lac());int[] arrayOfInt = dumpCells();JSONArray localJSONArray1 = new JSONArray();int k = 0;int m = arrayOfInt.length / 2;while (true) {if (k >= m) { localJSONObject1.put("cells", localJSONArray1); localObject = localJSONObject1; break;}int n = k * 2;int i1 = arrayOfInt[n];int i2 = k * 2 + 1;int i3 = arrayOfInt[i2];JSONObject localJSONObject7 = new JSONObject();localJSONObject7.put("cid", i1);localJSONObject7.put("asu", i3);localJSONArray1.put(localJSONObject7);k += 1;} } catch (JSONException localJSONException) {localObject = null; } }}public boolean isCdma() { if (!this.valid) update(); return this.isCdma;}public boolean isGsm() { if (!this.valid) update(); return this.isGsm;}public int lac() { if (!this.valid) update(); return this.lac;}public int lat() { if (!this.valid) update(); return this.lat;}public int lng() { if (!this.valid) update(); return this.lng;}public int mcc() { if (!this.valid) update(); return this.mcc;}public int mnc() { if (!this.valid) update(); return this.mnc;}public int nid() { if (!this.valid) update(); return this.nid;}public float score() { float f1 = 0f; int[] aryCells = null; int i = 0; float f2 = 0f; if (isCdma()) { f2 = 1065353216; return f2; } if (isGsm()) { f1 = 0.0F; aryCells = dumpCells(); int j = aryCells.length; if (i >= j)f2 = f1; } if(i <=0 ) { return 1065353216; } int m = aryCells[i]; for (i = 0; i < m; i++) { if ((m < 0) || (m > 31))f1 += 0.5F; elsef1 += 1.0F; } f2 = f1; return f2;}public int sid() { if (!this.valid) update(); return this.sid;}public void update() { this.isGsm = false; this.isCdma = false; this.cid = 0; this.lac = 0; this.mcc = 0; this.mnc = 0; CellLocation cellLocation = this.tel.getCellLocation(); int nPhoneType = this.tel.getPhoneType(); if (nPhoneType == 1 && cellLocation instanceof GsmCellLocation) { this.isGsm = true; GsmCellLocation gsmCellLocation = (GsmCellLocation) cellLocation; int nGSMCID = gsmCellLocation.getCid(); if (nGSMCID > 0) {if (nGSMCID != 65535) {this.cid = nGSMCID;this.lac = gsmCellLocation.getLac();} } } try { String strNetworkOperator = this.tel.getNetworkOperator(); int nNetworkOperatorLength = strNetworkOperator.length(); if (nNetworkOperatorLength != 5) {if (nNetworkOperatorLength != 6); } else {this.mcc = Integer.parseInt(strNetworkOperator.substring(0, 3));this.mnc = Integer.parseInt(strNetworkOperator.substring(3, nNetworkOperatorLength)); } if (this.tel.getPhoneType() == 2) {this.valid = true;Class<?> clsCellLocation = cellLocation.getClass();Class<?>[] aryClass = new Class[0];Method localMethod1 = clsCellLocation.getMethod("getBaseStationId", aryClass);Method localMethod2 = clsCellLocation.getMethod("getSystemId", aryClass);Method localMethod3 = clsCellLocation.getMethod("getNetworkId", aryClass);Object[] aryDummy = new Object[0];this.bid = ((Integer) localMethod1.invoke(cellLocation, aryDummy)).intValue();this.sid = ((Integer) localMethod2.invoke(cellLocation, aryDummy)).intValue();this.nid = ((Integer) localMethod3.invoke(cellLocation, aryDummy)).intValue();Method localMethod7 = clsCellLocation.getMethod("getBaseStationLatitude", aryClass);Method localMethod8 = clsCellLocation.getMethod("getBaseStationLongitude", aryClass);this.lat = ((Integer) localMethod7.invoke(cellLocation, aryDummy)).intValue();this.lng = ((Integer) localMethod8.invoke(cellLocation, aryDummy)).intValue();this.isCdma = true; } } catch (Exception ex) { Log.e("CellInfoManager", ex.getMessage()); }}class CellInfoListener extends PhoneStateListener { CellInfoListener(CellInfoManager manager) { } public void onCellLocationChanged(CellLocation paramCellLocation) { CellInfoManager.this.valid = false; } public void onSignalStrengthChanged(int paramInt) { CellInfoManager.this.asu = paramInt; }}}
WifiInfoManager
import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.json.JSONArray;import org.json.JSONObject;import android.content.Context;import android.net.wifi.ScanResult;import android.net.wifi.WifiManager;import android.util.Log;public class WifiInfoManager {private WifiManager wifiManager;public WifiInfoManager(Context paramContext) { this.wifiManager = (WifiManager) paramContext.getSystemService(Context.WIFI_SERVICE);}public List<WifiInfo> dump() { if (!this.wifiManager.isWifiEnabled()) { return new ArrayList<WifiInfo>(); } android.net.wifi.WifiInfo wifiConnection = this.wifiManager.getConnectionInfo(); WifiInfo currentWIFI = null; if (wifiConnection != null) { String s = wifiConnection.getBSSID(); int i = wifiConnection.getRssi(); String s1 = wifiConnection.getSSID(); currentWIFI = new WifiInfo(s, i, s1); } ArrayList<WifiInfo> lsAllWIFI = new ArrayList<WifiInfo>(); if (currentWIFI != null) { lsAllWIFI.add(currentWIFI); } List<ScanResult> lsScanResult = this.wifiManager.getScanResults(); for (ScanResult result : lsScanResult) { WifiInfo scanWIFI = new WifiInfo(result); if (!scanWIFI.equals(currentWIFI))lsAllWIFI.add(scanWIFI); } return lsAllWIFI;}public boolean isWifiEnabled() { return this.wifiManager.isWifiEnabled();}public JSONArray wifiInfo() { JSONArray jsonArray = new JSONArray(); for (WifiInfo wifi : dump()) { JSONObject localJSONObject = wifi.info(); jsonArray.put(localJSONObject); } return jsonArray;}public WifiManager wifiManager() { return this.wifiManager;}public JSONArray wifiTowers() { JSONArray jsonArray = new JSONArray(); try { Iterator<WifiInfo> localObject = dump().iterator(); while (true) {if (!(localObject).hasNext()) {return jsonArray;}jsonArray.put(localObject.next().wifi_tower()); } } catch (Exception localException) { Log.e("location", localException.getMessage()); } return jsonArray;}public class WifiInfo implements Comparable<WifiInfo> { public int compareTo(WifiInfo wifiinfo) { int i = wifiinfo.dBm; int j = dBm; return i - j; } public boolean equals(Object obj) { boolean flag = false; if (obj == this) {flag = true;return flag; } else {if (obj instanceof WifiInfo) {WifiInfo wifiinfo = (WifiInfo) obj;int i = wifiinfo.dBm;int j = dBm;if (i == j) { String s = wifiinfo.bssid; String s1 = bssid; if (s.equals(s1)) { flag = true; return flag; }}flag = false;} else {flag = false;} } return flag; } public int hashCode() { int i = dBm; int j = bssid.hashCode(); return i ^ j; } public JSONObject info() { JSONObject jsonobject = new JSONObject(); try {String s = bssid;jsonobject.put("mac", s);String s1 = ssid;jsonobject.put("ssid", s1);int i = dBm;jsonobject.put("dbm", i); } catch (Exception ex) { } return jsonobject; } public JSONObject wifi_tower() { JSONObject jsonobject = new JSONObject(); try {String s = bssid;jsonobject.put("mac_address", s);int i = dBm;jsonobject.put("signal_strength", i);String s1 = ssid;jsonobject.put("ssid", s1);jsonobject.put("age", 0); } catch (Exception ex) { } return jsonobject; } public final String bssid; public final int dBm; public final String ssid; public WifiInfo(ScanResult scanresult) { String s = scanresult.BSSID; bssid = s; int i = scanresult.level; dBm = i; String s1 = scanresult.SSID; ssid = s1; } public WifiInfo(String s, int i, String s1) { bssid = s; dBm = i; ssid = s1; }}}
CellLocationManager
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.client.methods.HttpPost;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.util.EntityUtils;import org.json.JSONArray;import org.json.JSONObject;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.net.wifi.WifiManager;import android.os.Handler;import android.os.Message;import android.telephony.CellLocation;import android.util.Log;import android.widget.Toast;import com.google.android.photostream.UserTask;public abstract class CellLocationManager {public static int CHECK_INTERVAL = 15000;public static boolean ENABLE_WIFI = true;private static boolean IS_DEBUG = false;private static final int STATE_COLLECTING = 2;private static final int STATE_IDLE = 0;private static final int STATE_READY = 1;private static final int STATE_SENDING = 3;private static final int MESSAGE_INITIALIZE = 1;private static final int MESSAGE_COLLECTING_CELL = 2;private static final int MESSAGE_COLLECTING_WIFI = 5;private static final int MESSAGE_BEFORE_FINISH = 10;private int accuracy;private int bid;private CellInfoManager cellInfoManager;private Context context;private boolean disableWifiAfterScan;private int[] aryGsmCells;private double latitude;private double longitude;private MyLooper looper;private boolean paused;private final BroadcastReceiver receiver;private long startScanTimestamp;private int state;private Task task;private long timestamp;private boolean waiting4WifiEnable;private WifiInfoManager wifiManager;public CellLocationManager(Context context, CellInfoManager cellinfomanager, WifiInfoManager wifiinfomanager) { receiver = new CellLocationManagerBroadcastReceiver(); this.context = context.getApplicationContext(); cellInfoManager = cellinfomanager; wifiManager = wifiinfomanager;}private void debug(Object paramObject) { if (IS_DEBUG) { System.out.println(paramObject); String str = String.valueOf(paramObject); Toast.makeText(this.context, str, Toast.LENGTH_SHORT).show(); }}public int accuracy() { return this.accuracy;}public double latitude() { return this.latitude;}public double longitude() { return this.longitude;}public abstract void onLocationChanged();public void pause() { if (state > 0 && !paused) { looper.removeMessages(MESSAGE_BEFORE_FINISH); paused = true; }}public void requestUpdate() { if (state != STATE_READY) { return; } boolean bStartScanSuccessful = false; CellLocation.requestLocationUpdate(); state = STATE_COLLECTING; looper.sendEmptyMessage(MESSAGE_INITIALIZE); if (wifiManager.wifiManager().isWifiEnabled()) { bStartScanSuccessful = wifiManager.wifiManager().startScan(); waiting4WifiEnable = false; } else { startScanTimestamp = System.currentTimeMillis(); if (!ENABLE_WIFI || !wifiManager.wifiManager().setWifiEnabled(true)) {int nDelay = 0;if (!bStartScanSuccessful)nDelay = 8000;looper.sendEmptyMessageDelayed(MESSAGE_COLLECTING_WIFI, nDelay);debug("CELL UPDATE"); } else {waiting4WifiEnable = true; } }}public void resume() { if (state > 0 && paused) { paused = false; looper.removeMessages(MESSAGE_BEFORE_FINISH); looper.sendEmptyMessage(MESSAGE_BEFORE_FINISH); }}public void start() { if (state <= STATE_IDLE) { Log.i("CellLocationManager", "Starting..."); context.registerReceiver(receiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); context.registerReceiver(receiver, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)); looper = new MyLooper(); state = STATE_READY; paused = false; waiting4WifiEnable = false; disableWifiAfterScan = false; debug("CELL LOCATION START"); requestUpdate(); }}public void stop() { if (state > STATE_IDLE) { context.unregisterReceiver(receiver); debug("CELL LOCATION STOP"); looper = null; state = STATE_IDLE; if (disableWifiAfterScan) {disableWifiAfterScan = false;wifiManager.wifiManager().setWifiEnabled(false); } }}public long timestamp() { return this.timestamp;}protected boolean isConnectedWithInternet() { ConnectivityManager conManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = conManager.getActiveNetworkInfo(); if (networkInfo != null) { return networkInfo.isAvailable(); } return false;}private class MyLooper extends Handler { private float fCellScore; private JSONArray objCellTowersJson; public void handleMessage(Message paramMessage) { if(CellLocationManager.this.looper != this)return; boolean flag = true; switch (paramMessage.what) { default:break; case MESSAGE_INITIALIZE:this.objCellTowersJson = null;this.fCellScore = 1.401298E-045F; case MESSAGE_COLLECTING_CELL:if (CellLocationManager.this.state != CellLocationManager.STATE_COLLECTING)break;JSONArray objCellTowers = CellLocationManager.this.cellInfoManager.cellTowers();float fCellScore = CellLocationManager.this.cellInfoManager.score();if (objCellTowers != null) {float fCurrentCellScore = this.fCellScore;if (fCellScore > fCurrentCellScore) { this.objCellTowersJson = objCellTowers; this.fCellScore = fCellScore;}}this.sendEmptyMessageDelayed(MESSAGE_COLLECTING_CELL, 600L);break; case MESSAGE_COLLECTING_WIFI:if (CellLocationManager.this.state != CellLocationManager.STATE_COLLECTING)break;this.removeMessages(MESSAGE_COLLECTING_CELL);this.removeMessages(MESSAGE_BEFORE_FINISH);// if (CellLocationManager.this.disableWifiAfterScan && CellLocationManager.this.wifiManager.wifiManager().setWifiEnabled(true))// CellLocationManager.this.disableWifiAfterScan = false;CellLocationManager.this.state = CellLocationManager.STATE_SENDING;if (CellLocationManager.this.task != null)CellLocationManager.this.task.cancel(true);int[] aryCell = null;if (CellLocationManager.this.cellInfoManager.isGsm())aryCell = CellLocationManager.this.cellInfoManager.dumpCells();int nBid = CellLocationManager.this.cellInfoManager.bid();CellLocationManager.this.task = new CellLocationManager.Task(aryCell, nBid);JSONArray[] aryJsonArray = new JSONArray[2];aryJsonArray[0] = this.objCellTowersJson;aryJsonArray[1] = CellLocationManager.this.wifiManager.wifiTowers();if(this.objCellTowersJson != null)Log.i("CellTownerJSON", this.objCellTowersJson.toString());if(aryJsonArray[1] != null)Log.i("WIFITownerJSON", aryJsonArray[1].toString());CellLocationManager.this.debug("Post json");CellLocationManager.this.task.execute(aryJsonArray);break; case MESSAGE_BEFORE_FINISH:if (CellLocationManager.this.state != CellLocationManager.STATE_READY || CellLocationManager.this.paused)break;// L7if (CellLocationManager.this.disableWifiAfterScan && CellLocationManager.this.wifiManager.wifiManager().setWifiEnabled(false))CellLocationManager.this.disableWifiAfterScan = false;if (!CellLocationManager.this.cellInfoManager.isGsm()) {// L9if (CellLocationManager.this.bid == CellLocationManager.this.cellInfoManager.bid()) { flag = true;} else { flag = false;}// L14if (flag) { requestUpdate();} else { this.sendEmptyMessageDelayed(10, CellLocationManager.CHECK_INTERVAL);}} else {// L8if (CellLocationManager.this.aryGsmCells == null || CellLocationManager.this.aryGsmCells.length == 0) { // L10 flag = true;} else { int[] aryCells = CellLocationManager.this.cellInfoManager.dumpCells(); if (aryCells != null && aryCells.length != 0) { // L13 int nFirstCellId = CellLocationManager.this.aryGsmCells[0]; if (nFirstCellId == aryCells[0]) {// L16int cellLength = CellLocationManager.this.aryGsmCells.length / 2;List<Integer> arraylist = new ArrayList<Integer>(cellLength);List<Integer> arraylist1 = new ArrayList<Integer>(aryCells.length / 2);int nIndex = 0;int nGSMCellLength = CellLocationManager.this.aryGsmCells.length;while (nIndex < nGSMCellLength) {// goto L18arraylist.add(CellLocationManager.this.aryGsmCells[nIndex]);nIndex += 2;}// goto L17nIndex = 0;while (nIndex < aryCells.length) {// goto L20arraylist1.add(aryCells[nIndex]);nIndex += 2;}// goto L19int nCounter = 0;for(Iterator<Integer> iterator = arraylist.iterator(); iterator.hasNext();) {// goto L22if (arraylist1.contains(iterator.next())) nCounter++;}// goto L21int k4 = arraylist.size() - nCounter;int l4 = arraylist1.size() - nCounter;if (k4 + l4 > nCounter)flag = true;elseflag = false;if (flag) {StringBuilder stringbuilder = new StringBuilder(k4).append(" + ");stringbuilder.append(l4).append(" > ");stringbuilder.append(nCounter);CellLocationManager.this.debug(stringbuilder.toString());}break; } else {// L15flag = true;CellLocationManager.this.debug("PRIMARY CELL CHANGED");// goto L14if (flag) {requestUpdate();} else {this.sendEmptyMessageDelayed(MESSAGE_BEFORE_FINISH, CellLocationManager.CHECK_INTERVAL);} } } else { // L12 flag = true; // goto L14 if (flag) {requestUpdate(); } else {this.sendEmptyMessageDelayed(MESSAGE_BEFORE_FINISH,CellLocationManager.CHECK_INTERVAL); } }}} } }}class Task extends UserTask<JSONArray, Void, Void> { int accuracy; int bid; int[] cells; double lat; double lng; long time; public Task(int[] aryCell, int bid) { this.time = System.currentTimeMillis(); this.cells = aryCell; this.bid = bid; } public Void doInBackground(JSONArray[] paramArrayOfJSONArray) { try {JSONObject jsonObject = new JSONObject();jsonObject.put("version", "1.1.0");jsonObject.put("host", "maps.google.com");jsonObject.put("address_language", "zh_CN");jsonObject.put("request_address", true);jsonObject.put("radio_type", "gsm");jsonObject.put("carrier", "HTC");JSONArray cellJson = paramArrayOfJSONArray[0];jsonObject.put("cell_towers", cellJson);JSONArray wifiJson = paramArrayOfJSONArray[1];jsonObject.put("wifi_towers", wifiJson);DefaultHttpClient localDefaultHttpClient = new DefaultHttpClient();HttpPost localHttpPost = new HttpPost("http://www.google.com/loc/json");String strJson = jsonObject.toString();StringEntity objJsonEntity = new StringEntity(strJson);localHttpPost.setEntity(objJsonEntity);HttpResponse objResponse = localDefaultHttpClient.execute(localHttpPost);int nStateCode = objResponse.getStatusLine().getStatusCode();HttpEntity httpEntity = objResponse.getEntity();byte[] arrayOfByte = null;if (nStateCode / 100 == 2)arrayOfByte = EntityUtils.toByteArray(httpEntity);httpEntity.consumeContent();String strResponse = new String(arrayOfByte, "UTF-8");jsonObject = new JSONObject(strResponse);this.lat = jsonObject.getJSONObject("location").getDouble("latitude");this.lng = jsonObject.getJSONObject("location").getDouble("longitude");this.accuracy = jsonObject.getJSONObject("location").getInt("accuracy");; } catch (Exception localException) {return null; } return null; } public void onPostExecute(Void paramVoid) { if (CellLocationManager.this.state != CellLocationManager.STATE_SENDING || CellLocationManager.this.task != this)return; if ((this.lat != 0.0D) && (this.lng != 0.0D)) {CellLocationManager.this.timestamp = this.time;CellLocationManager.this.latitude = this.lat;CellLocationManager.this.longitude = this.lng;CellLocationManager.this.accuracy = this.accuracy;CellLocationManager.this.aryGsmCells = this.cells;CellLocationManager.this.bid = this.bid;StringBuilder sb = new StringBuilder("CELL LOCATION DONE: (");sb.append(this.lat).append(",").append(this.lng).append(")");CellLocationManager.this.debug(sb.toString());CellLocationManager.this.state = STATE_READY;CellLocationManager.this.looper.sendEmptyMessageDelayed(MESSAGE_BEFORE_FINISH, CellLocationManager.CHECK_INTERVAL);CellLocationManager.this.onLocationChanged(); } else {CellLocationManager.this.task = null;CellLocationManager.this.state = CellLocationManager.STATE_READY;CellLocationManager.this.looper.sendEmptyMessageDelayed(MESSAGE_BEFORE_FINISH, 5000L); } }}private class CellLocationManagerBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context arg0, Intent intent) { // access$0 state // 1 debug // access$2 loop // 3 startScanTimestamp // 4 disableWifiAfterScan // 5 wifimanager if (CellLocationManager.this.state != CellLocationManager.STATE_COLLECTING)return; String s = intent.getAction(); if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(s)) { // goto _L4; else goto _L3 // _L3:CellLocationManager.this.debug("WIFI SCAN COMPLETE");CellLocationManager.this.looper.removeMessages(MESSAGE_COLLECTING_WIFI);long lInterval = System.currentTimeMillis() - CellLocationManager.this.startScanTimestamp;if (lInterval > 4000L)CellLocationManager.this.looper.sendEmptyMessageDelayed(MESSAGE_COLLECTING_WIFI, 4000L);elseCellLocationManager.this.looper.sendEmptyMessage(MESSAGE_COLLECTING_WIFI); } else {// _L4:if (!CellLocationManager.this.waiting4WifiEnable)return;String s1 = intent.getAction();if (!WifiManager.WIFI_STATE_CHANGED_ACTION.equals(s1))return;int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 4);// _L5:if (wifiState == WifiManager.WIFI_STATE_ENABLING) {boolean flag2 = CellLocationManager.this.wifiManager.wifiManager().startScan();// _L8:CellLocationManager.this.disableWifiAfterScan = true;CellLocationManager.this.paused = false;// int i = flag2 ? 1 : 0;// int nDelay = i != 0 ? 8000 : 0;// CellLocationManager.this.looper.sendEmptyMessageDelayed(MESSAGE_COLLECTING_WIFI, nDelay);CellLocationManager.this.debug("WIFI ENABLED");} } }}}
调用方法:
CellInfoManager cellManager = new CellInfoManager(this); WifiInfoManager wifiManager = new WifiInfoManager(this); CellLocationManager locationManager = new CellLocationManager(this, cellManager, wifiManager) { @Override public void onLocationChanged() {txtAutoNaviInfo.setText(this.latitude() + "-" + this.longitude());this.stop(); } }; locationManager.start();
如果还想同时使用GPS定位,其实也很简单,可以和FourSquare提供的BestLocationListener结合起来,将上面那段代码添加到BestLocationListener的register方法里:
public void register(LocationManager locationManager, boolean gps, Context context) {if (DEBUG) Log.d(TAG, "Registering this location listener: " + this.toString());long updateMinTime = SLOW_LOCATION_UPDATE_MIN_TIME;long updateMinDistance = SLOW_LOCATION_UPDATE_MIN_DISTANCE;if (gps) {updateMinTime = LOCATION_UPDATE_MIN_TIME;updateMinDistance = LOCATION_UPDATE_MIN_DISTANCE;}List<String> providers = locationManager.getProviders(true);int providersCount = providers.size();if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){setChanged();notifyObservers(null);}for (int i = 0; i < providersCount; i++) {String providerName = providers.get(i);if (locationManager.isProviderEnabled(providerName)) {updateLocation(locationManager.getLastKnownLocation(providerName));}// Only register with GPS if we"ve explicitly allowed it.if (gps || !LocationManager.GPS_PROVIDER.equals(providerName)) {locationManager.requestLocationUpdates(providerName, updateMinTime,updateMinDistance, this);}}if(cellLocationManager == null) {CellInfoManager cellManager = new CellInfoManager(context); WifiInfoManager wifiManager = new WifiInfoManager(context); cellLocationManager = new CellLocationManager(context, cellManager, wifiManager) {@Overridepublic void onLocationChanged() {if ((latitude() == 0.0D) || (longitude() == 0.0D)) return;Location result = new Location("CellLocationManager");result.setLatitude(latitude());result.setLongitude(longitude());result.setAccuracy(accuracy());onBestLocationChanged(result);this.stop();} };}//cellLocationManager.stop();cellLocationManager.start();//LocationController controller = LocationController.requestLocationUpdates("", updateMinTime,updateMinDistance, this, context);//controller.requestCurrentLocation();}