欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

在Android里完美实现基站和WIFI定位

程序员文章站 2023-02-02 12:59:25
不过其实只要明白了基站/wifi定位的原理,自己实现基站/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();
  }