在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(); }