hao1nan 发表于 2015-10-2 12:11:34

Android里实现基站和WIFI定位

  

  大部分国产的Android定制机里不支持最简单实用的基站和WIFI定位,只能使用速度慢而耗电的GPS定位,但OPhone和华为/中兴生产的一些Android定制机却占据了一定的市场,因此导致了很多使用了定位技术的Andorid应用挺尴尬的。
  
           不过其实只要明白了基站/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定位完美结合。以下是相关的代码:
  


view plaincopy
[*]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;
[*]                     aryCell = cid;
[*]                     aryCell = -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);
[*]                            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;
[*]                     return aryCells;
[*]            }
[*]   
[*]            List<NeighboringCellInfo> lsCellInfo = this.tel.getNeighboringCellInfo();
[*]            if (lsCellInfo == null || lsCellInfo.size() == 0) {
[*]                     aryCells = new int;
[*]                     int i = cid();
[*]                     aryCells = i;
[*]                     return aryCells;
[*]            }
[*]            int[] arrayOfInt1 = new int;
[*]            int j = 0 + 1;
[*]            int k = cid();
[*]            arrayOfInt1 = k;
[*]            int m = j + 1;
[*]            int n = asu();
[*]            arrayOfInt1 = 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 = i2;
[*]                     m = i3 + 1;
[*]                     int i4 = localNeighboringCellInfo.getRssi();
[*]                     arrayOfInt1 = i4;
[*]            }
[*]            int[] arrayOfInt2 = new int;
[*]            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;
[*]                                 int i2 = k * 2 + 1;
[*]                                 int i3 = arrayOfInt;
[*]                                 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;
[*]            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;
[*]                            Method localMethod1 = clsCellLocation.getMethod("getBaseStationId", aryClass);
[*]                            Method localMethod2 = clsCellLocation.getMethod("getSystemId", aryClass);
[*]                            Method localMethod3 = clsCellLocation.getMethod("getNetworkId", aryClass);
[*]                            Object[] aryDummy = new Object;   
[*]                            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;
[*]                            aryJsonArray = this.objCellTowersJson;
[*]                            aryJsonArray = CellLocationManager.this.wifiManager.wifiTowers();
[*]                            if(this.objCellTowersJson != null)
[*]                                 Log.i("CellTownerJSON", this.objCellTowersJson.toString());
[*]                            if(aryJsonArray != null)
[*]                                 Log.i("WIFITownerJSON", aryJsonArray.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;
[*]                                                 if (nFirstCellId == aryCells) {
[*]                                                      // 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 += 2;
[*]                                                      }
[*]                                                      // goto L17
[*]                                                      nIndex = 0;
[*]                                                      while (nIndex < aryCells.length) {
[*]                                                               // goto L20
[*]                                                               arraylist1.add(aryCells);
[*]                                                               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;
[*]                            jsonObject.put("cell_towers", cellJson);
[*]                            JSONArray wifiJson = paramArrayOfJSONArray;
[*]                            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();
[*]    }
页: [1]
查看完整版本: Android里实现基站和WIFI定位