在Android里完美实现基站和WIFI定位
不过其实只要明白了基站/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; else f1 += 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; // L7 if (CellLocationManager.this.disableWifiAfterScan && CellLocationManager.this.wifiManager.wifiManager().setWifiEnabled(false)) CellLocationManager.this.disableWifiAfterScan = false; if (!CellLocationManager.this.cellInfoManager.isGsm()) { // L9 if (CellLocationManager.this.bid == CellLocationManager.this.cellInfoManager.bid()) { flag = true; } else { flag = false; } // L14 if (flag) { requestUpdate(); } else { this.sendEmptyMessageDelayed(10, CellLocationManager.CHECK_INTERVAL); } } else { // L8 if (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]) { // L16 int 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 L18 arraylist.add(CellLocationManager.this.aryGsmCells[nIndex]); nIndex += 2; } // goto L17 nIndex = 0; while (nIndex < aryCells.length) { // goto L20 arraylist1.add(aryCells[nIndex]); nIndex += 2; } // goto L19 int nCounter = 0; for(Iterator<Integer> iterator = arraylist.iterator(); iterator.hasNext();) { // goto L22 if (arraylist1.contains(iterator.next())) nCounter++; } // goto L21 int k4 = arraylist.size() - nCounter; int l4 = arraylist1.size() - nCounter; if (k4 + l4 > nCounter) flag = true; else flag = false; if (flag) { StringBuilder stringbuilder = new StringBuilder(k4).append(" + "); stringbuilder.append(l4).append(" > "); stringbuilder.append(nCounter); CellLocationManager.this.debug(stringbuilder.toString()); } break; } else { // L15 flag = true; CellLocationManager.this.debug("PRIMARY CELL CHANGED"); // goto L14 if (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); else CellLocationManager.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) { @Override public 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(); }