在Android里完美实现基站和WIFI定位
不过其实只要明白了基站/WIFI定位的原理,自己实现基站/WIFI定位其实不难。基站定位一般有几种,第一种是利用手机附近的三个基站进行三角定位,由于每个基站的位置是固定的,利用电磁波在这三个基站间中转所需要时间来算出手机所在的坐标;第二种则是利用获取最近的基站的信息,其中包括基站id,locationareacode、mobilecountrycode、mobilenetworkcode和信号强度,将这些数据发送到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
importjava.lang.reflect.Method;
importjava.util.Iterator;
importjava.util.List;
importorg.json.JSONArray;
importorg.json.JSONException;
importorg.json.JSONObject;
importandroid.content.Context;
importandroid.telephony.CellLocation;
importandroid.telephony.NeighboringCellInfo;
importandroid.telephony.PhoneStateListener;
importandroid.telephony.TelephonyManager;
importandroid.telephony.gsm.GsmCellLocation;
importandroid.util.Log;
publicclassCellInfoManager{
privateintasu;
privateintbid;
privateintcid;
privatebooleanisCdma;
privatebooleanisGsm;
privateintlac;
privateintlat;
privatefinalPhoneStateListenerlistener;
privateintlng;
privateintmcc;
privateintmnc;
privateintnid;
privateintsid;
privateTelephonyManagertel;
privatebooleanvalid;
privateContextcontext;
publicCellInfoManager(ContextparamContext){
this.listener=newCellInfoListener(this);
tel=(TelephonyManager)paramContext.getSystemService(Context.TELEPHONY_SERVICE);
this.tel.listen(this.listener,PhoneStateListener.LISTEN_CELL_LOCATION|PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
context=paramContext;
}
publicstaticintdBm(inti){
intj;
if(i>=0&&i<=31)
j=i*2+-113;
else
j=0;
returnj;
}
publicintasu(){
returnthis.asu;
}
publicintbid(){
if(!this.valid)
update();
returnthis.bid;
}
publicJSONObjectcdmaInfo(){
if(!isCdma()){
returnnull;
}
JSONObjectjsonObject=newJSONObject();
try{
jsonObject.put("bid",bid());
jsonObject.put("sid",sid());
jsonObject.put("nid",nid());
jsonObject.put("lat",lat());
jsonObject.put("lng",lng());
}catch(JSONExceptionex){
jsonObject=null;
Log.e("CellInfoManager",ex.getMessage());
}
returnjsonObject;
}
publicJSONArraycellTowers(){
JSONArrayjsonarray=newJSONArray();
intlat;
intmcc;
intmnc;
intaryCell[]=dumpCells();
lat=lac();
mcc=mcc();
mnc=mnc();
if(aryCell==null||aryCell.length<2){
aryCell=newint[2];
aryCell[0]=cid;
aryCell[1]=-60;
}
for(inti=0;i<aryCell.length;i+=2){
try{
intj2=dBm(i+1);
JSONObjectjsonobject=newJSONObject();
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(Exceptionex){
ex.printStackTrace();
Log.e("CellInfoManager",ex.getMessage());
}
}
if(isCdma())
jsonarray=newJSONArray();
returnjsonarray;
}
publicintcid(){
if(!this.valid)
update();
returnthis.cid;
}
publicint[]dumpCells(){
int[]aryCells;
if(cid()==0){
aryCells=newint[0];
returnaryCells;
}
List<NeighboringCellInfo>lsCellInfo=this.tel.getNeighboringCellInfo();
if(lsCellInfo==null||lsCellInfo.size()==0){
aryCells=newint[1];
inti=cid();
aryCells[0]=i;
returnaryCells;
}
int[]arrayOfInt1=newint[lsCellInfo.size()*2+2];
intj=0+1;
intk=cid();
arrayOfInt1[0]=k;
intm=j+1;
intn=asu();
arrayOfInt1[j]=n;
Iterator<NeighboringCellInfo>iter=lsCellInfo.iterator();
while(true){
if(!iter.hasNext()){
break;
}
NeighboringCellInfolocalNeighboringCellInfo=(NeighboringCellInfo)iter.next();
inti2=localNeighboringCellInfo.getCid();
if((i2<=0)||(i2==65535))
continue;
inti3=m+1;
arrayOfInt1[m]=i2;
m=i3+1;
inti4=localNeighboringCellInfo.getRssi();
arrayOfInt1[i3]=i4;
}
int[]arrayOfInt2=newint[m];
System.arraycopy(arrayOfInt1,0,arrayOfInt2,0,m);
aryCells=arrayOfInt2;
returnaryCells;
}
publicJSONObjectgsmInfo(){
if(!isGsm()){
returnnull;
}
JSONObjectlocalObject=null;
while(true){
try{
JSONObjectlocalJSONObject1=newJSONObject();
Stringstr1=this.tel.getNetworkOperatorName();
localJSONObject1.put("operator",str1);
Stringstr2=this.tel.getNetworkOperator();
if((str2.length()==5)||(str2.length()==6)){
Stringstr3=str2.substring(0,3);
Stringstr4=str2.substring(3,str2.length());
localJSONObject1.put("mcc",str3);
localJSONObject1.put("mnc",str4);
}
localJSONObject1.put("lac",lac());
int[]arrayOfInt=dumpCells();
JSONArraylocalJSONArray1=newJSONArray();
intk=0;
intm=arrayOfInt.length/2;
while(true){
if(k>=m){
localJSONObject1.put("cells",localJSONArray1);
localObject=localJSONObject1;
break;
}
intn=k*2;
inti1=arrayOfInt[n];
inti2=k*2+1;
inti3=arrayOfInt[i2];
JSONObjectlocalJSONObject7=newJSONObject();
localJSONObject7.put("cid",i1);
localJSONObject7.put("asu",i3);
localJSONArray1.put(localJSONObject7);
k+=1;
}
}catch(JSONExceptionlocalJSONException){
localObject=null;
}
}
}
publicbooleanisCdma(){
if(!this.valid)
update();
returnthis.isCdma;
}
publicbooleanisGsm(){
if(!this.valid)
update();
returnthis.isGsm;
}
publicintlac(){
if(!this.valid)
update();
returnthis.lac;
}
publicintlat(){
if(!this.valid)
update();
returnthis.lat;
}
publicintlng(){
if(!this.valid)
update();
returnthis.lng;
}
publicintmcc(){
if(!this.valid)
update();
returnthis.mcc;
}
publicintmnc(){
if(!this.valid)
update();
returnthis.mnc;
}
publicintnid(){
if(!this.valid)
update();
returnthis.nid;
}
publicfloatscore(){
floatf1=0f;
int[]aryCells=null;
inti=0;
floatf2=0f;
if(isCdma()){
f2=1065353216;
returnf2;
}
if(isGsm()){
f1=0.0F;
aryCells=dumpCells();
intj=aryCells.length;
if(i>=j)
f2=f1;
}
if(i<=0){
return1065353216;
}
intm=aryCells[i];
for(i=0;i<m;i++){
if((m<0)||(m>31))
f1+=0.5F;
else
f1+=1.0F;
}
f2=f1;
returnf2;
}
publicintsid(){
if(!this.valid)
update();
returnthis.sid;
}
publicvoidupdate(){
this.isGsm=false;
this.isCdma=false;
this.cid=0;
this.lac=0;
this.mcc=0;
this.mnc=0;
CellLocationcellLocation=this.tel.getCellLocation();
intnPhoneType=this.tel.getPhoneType();
if(nPhoneType==1&&cellLocationinstanceofGsmCellLocation){
this.isGsm=true;
GsmCellLocationgsmCellLocation=(GsmCellLocation)cellLocation;
intnGSMCID=gsmCellLocation.getCid();
if(nGSMCID>0){
if(nGSMCID!=65535){
this.cid=nGSMCID;
this.lac=gsmCellLocation.getLac();
}
}
}
try{
StringstrNetworkOperator=this.tel.getNetworkOperator();
intnNetworkOperatorLength=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=newClass[0];
MethodlocalMethod1=clsCellLocation.getMethod("getBaseStationId",aryClass);
MethodlocalMethod2=clsCellLocation.getMethod("getSystemId",aryClass);
MethodlocalMethod3=clsCellLocation.getMethod("getNetworkId",aryClass);
Object[]aryDummy=newObject[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();
MethodlocalMethod7=clsCellLocation.getMethod("getBaseStationLatitude",aryClass);
MethodlocalMethod8=clsCellLocation.getMethod("getBaseStationLongitude",aryClass);
this.lat=((Integer)localMethod7.invoke(cellLocation,aryDummy)).intValue();
this.lng=((Integer)localMethod8.invoke(cellLocation,aryDummy)).intValue();
this.isCdma=true;
}
}catch(Exceptionex){
Log.e("CellInfoManager",ex.getMessage());
}
}
classCellInfoListenerextendsPhoneStateListener{
CellInfoListener(CellInfoManagermanager){
}
publicvoidonCellLocationChanged(CellLocationparamCellLocation){
CellInfoManager.this.valid=false;
}
publicvoidonSignalStrengthChanged(intparamInt){
CellInfoManager.this.asu=paramInt;
}
}
}
WifiInfoManager
importjava.util.ArrayList;
importjava.util.Iterator;
importjava.util.List;
importorg.json.JSONArray;
importorg.json.JSONObject;
importandroid.content.Context;
importandroid.net.wifi.ScanResult;
importandroid.net.wifi.WifiManager;
importandroid.util.Log;
publicclassWifiInfoManager{
privateWifiManagerwifiManager;
publicWifiInfoManager(ContextparamContext){
this.wifiManager=(WifiManager)paramContext.getSystemService(Context.WIFI_SERVICE);
}
publicList<WifiInfo>dump(){
if(!this.wifiManager.isWifiEnabled()){
returnnewArrayList<WifiInfo>();
}
android.net.wifi.WifiInfowifiConnection=this.wifiManager.getConnectionInfo();
WifiInfocurrentWIFI=null;
if(wifiConnection!=null){
Strings=wifiConnection.getBSSID();
inti=wifiConnection.getRssi();
Strings1=wifiConnection.getSSID();
currentWIFI=newWifiInfo(s,i,s1);
}
ArrayList<WifiInfo>lsAllWIFI=newArrayList<WifiInfo>();
if(currentWIFI!=null){
lsAllWIFI.add(currentWIFI);
}
List<ScanResult>lsScanResult=this.wifiManager.getScanResults();
for(ScanResultresult:lsScanResult){
WifiInfoscanWIFI=newWifiInfo(result);
if(!scanWIFI.equals(currentWIFI))
lsAllWIFI.add(scanWIFI);
}
returnlsAllWIFI;
}
publicbooleanisWifiEnabled(){
returnthis.wifiManager.isWifiEnabled();
}
publicJSONArraywifiInfo(){
JSONArrayjsonArray=newJSONArray();
for(WifiInfowifi:dump()){
JSONObjectlocalJSONObject=wifi.info();
jsonArray.put(localJSONObject);
}
returnjsonArray;
}
publicWifiManagerwifiManager(){
returnthis.wifiManager;
}
publicJSONArraywifiTowers(){
JSONArrayjsonArray=newJSONArray();
try{
Iterator<WifiInfo>localObject=dump().iterator();
while(true){
if(!(localObject).hasNext()){
returnjsonArray;
}
jsonArray.put(localObject.next().wifi_tower());
}
}catch(ExceptionlocalException){
Log.e("location",localException.getMessage());
}
returnjsonArray;
}
publicclassWifiInfoimplementsComparable<WifiInfo>{
publicintcompareTo(WifiInfowifiinfo){
inti=wifiinfo.dBm;
intj=dBm;
returni-j;
}
publicbooleanequals(Objectobj){
booleanflag=false;
if(obj==this){
flag=true;
returnflag;
}else{
if(objinstanceofWifiInfo){
WifiInfowifiinfo=(WifiInfo)obj;
inti=wifiinfo.dBm;
intj=dBm;
if(i==j){
Strings=wifiinfo.bssid;
Strings1=bssid;
if(s.equals(s1)){
flag=true;
returnflag;
}
}
flag=false;
}else{
flag=false;
}
}
returnflag;
}
publicinthashCode(){
inti=dBm;
intj=bssid.hashCode();
returni^j;
}
publicJSONObjectinfo(){
JSONObjectjsonobject=newJSONObject();
try{
Strings=bssid;
jsonobject.put("mac",s);
Strings1=ssid;
jsonobject.put("ssid",s1);
inti=dBm;
jsonobject.put("dbm",i);
}catch(Exceptionex){
}
returnjsonobject;
}
publicJSONObjectwifi_tower(){
JSONObjectjsonobject=newJSONObject();
try{
Strings=bssid;
jsonobject.put("mac_address",s);
inti=dBm;
jsonobject.put("signal_strength",i);
Strings1=ssid;
jsonobject.put("ssid",s1);
jsonobject.put("age",0);
}catch(Exceptionex){
}
returnjsonobject;
}
publicfinalStringbssid;
publicfinalintdBm;
publicfinalStringssid;
publicWifiInfo(ScanResultscanresult){
Strings=scanresult.BSSID;
bssid=s;
inti=scanresult.level;
dBm=i;
Strings1=scanresult.SSID;
ssid=s1;
}
publicWifiInfo(Strings,inti,Strings1){
bssid=s;
dBm=i;
ssid=s1;
}
}
}
CellLocationManager
importjava.util.ArrayList;
importjava.util.Iterator;
importjava.util.List;
importorg.apache.http.HttpEntity;
importorg.apache.http.HttpResponse;
importorg.apache.http.client.methods.HttpPost;
importorg.apache.http.entity.StringEntity;
importorg.apache.http.impl.client.DefaultHttpClient;
importorg.apache.http.util.EntityUtils;
importorg.json.JSONArray;
importorg.json.JSONObject;
importandroid.content.BroadcastReceiver;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.content.IntentFilter;
importandroid.net.ConnectivityManager;
importandroid.net.NetworkInfo;
importandroid.net.wifi.WifiManager;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.telephony.CellLocation;
importandroid.util.Log;
importandroid.widget.Toast;
importcom.google.android.photostream.UserTask;
publicabstractclassCellLocationManager{
publicstaticintCHECK_INTERVAL=15000;
publicstaticbooleanENABLE_WIFI=true;
privatestaticbooleanIS_DEBUG=false;
privatestaticfinalintSTATE_COLLECTING=2;
privatestaticfinalintSTATE_IDLE=0;
privatestaticfinalintSTATE_READY=1;
privatestaticfinalintSTATE_SENDING=3;
privatestaticfinalintMESSAGE_INITIALIZE=1;
privatestaticfinalintMESSAGE_COLLECTING_CELL=2;
privatestaticfinalintMESSAGE_COLLECTING_WIFI=5;
privatestaticfinalintMESSAGE_BEFORE_FINISH=10;
privateintaccuracy;
privateintbid;
privateCellInfoManagercellInfoManager;
privateContextcontext;
privatebooleandisableWifiAfterScan;
privateint[]aryGsmCells;
privatedoublelatitude;
privatedoublelongitude;
privateMyLooperlooper;
privatebooleanpaused;
privatefinalBroadcastReceiverreceiver;
privatelongstartScanTimestamp;
privateintstate;
privateTasktask;
privatelongtimestamp;
privatebooleanwaiting4WifiEnable;
privateWifiInfoManagerwifiManager;
publicCellLocationManager(Contextcontext,CellInfoManagercellinfomanager,WifiInfoManagerwifiinfomanager){
receiver=newCellLocationManagerBroadcastReceiver();
this.context=context.getApplicationContext();
cellInfoManager=cellinfomanager;
wifiManager=wifiinfomanager;
}
privatevoiddebug(ObjectparamObject){
if(IS_DEBUG){
System.out.println(paramObject);
Stringstr=String.valueOf(paramObject);
Toast.makeText(this.context,str,Toast.LENGTH_SHORT).show();
}
}
publicintaccuracy(){
returnthis.accuracy;
}
publicdoublelatitude(){
returnthis.latitude;
}
publicdoublelongitude(){
returnthis.longitude;
}
publicabstractvoidonLocationChanged();
publicvoidpause(){
if(state>0&&!paused){
looper.removeMessages(MESSAGE_BEFORE_FINISH);
paused=true;
}
}
publicvoidrequestUpdate(){
if(state!=STATE_READY){
return;
}
booleanbStartScanSuccessful=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)){
intnDelay=0;
if(!bStartScanSuccessful)
nDelay=8000;
looper.sendEmptyMessageDelayed(MESSAGE_COLLECTING_WIFI,nDelay);
debug("CELLUPDATE");
}else{
waiting4WifiEnable=true;
}
}
}
publicvoidresume(){
if(state>0&&paused){
paused=false;
looper.removeMessages(MESSAGE_BEFORE_FINISH);
looper.sendEmptyMessage(MESSAGE_BEFORE_FINISH);
}
}
publicvoidstart(){
if(state<=STATE_IDLE){
Log.i("CellLocationManager","Starting...");
context.registerReceiver(receiver,newIntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
context.registerReceiver(receiver,newIntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
looper=newMyLooper();
state=STATE_READY;
paused=false;
waiting4WifiEnable=false;
disableWifiAfterScan=false;
debug("CELLLOCATIONSTART");
requestUpdate();
}
}
publicvoidstop(){
if(state>STATE_IDLE){
context.unregisterReceiver(receiver);
debug("CELLLOCATIONSTOP");
looper=null;
state=STATE_IDLE;
if(disableWifiAfterScan){
disableWifiAfterScan=false;
wifiManager.wifiManager().setWifiEnabled(false);
}
}
}
publiclongtimestamp(){
returnthis.timestamp;
}
protectedbooleanisConnectedWithInternet(){
ConnectivityManagerconManager=(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfonetworkInfo=conManager.getActiveNetworkInfo();
if(networkInfo!=null){
returnnetworkInfo.isAvailable();
}
returnfalse;
}
privateclassMyLooperextendsHandler{
privatefloatfCellScore;
privateJSONArrayobjCellTowersJson;
publicvoidhandleMessage(MessageparamMessage){
if(CellLocationManager.this.looper!=this)
return;
booleanflag=true;
switch(paramMessage.what){
default:
break;
caseMESSAGE_INITIALIZE:
this.objCellTowersJson=null;
this.fCellScore=1.401298E-045F;
caseMESSAGE_COLLECTING_CELL:
if(CellLocationManager.this.state!=CellLocationManager.STATE_COLLECTING)
break;
JSONArrayobjCellTowers=CellLocationManager.this.cellInfoManager.cellTowers();
floatfCellScore=CellLocationManager.this.cellInfoManager.score();
if(objCellTowers!=null){
floatfCurrentCellScore=this.fCellScore;
if(fCellScore>fCurrentCellScore){
this.objCellTowersJson=objCellTowers;
this.fCellScore=fCellScore;
}
}
this.sendEmptyMessageDelayed(MESSAGE_COLLECTING_CELL,600L);
break;
caseMESSAGE_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();
intnBid=CellLocationManager.this.cellInfoManager.bid();
CellLocationManager.this.task=newCellLocationManager.Task(aryCell,nBid);
JSONArray[]aryJsonArray=newJSONArray[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("Postjson");
CellLocationManager.this.task.execute(aryJsonArray);
break;
caseMESSAGE_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
intnFirstCellId=CellLocationManager.this.aryGsmCells[0];
if(nFirstCellId==aryCells[0]){
//L16
intcellLength=CellLocationManager.this.aryGsmCells.length/2;
List<Integer>arraylist=newArrayList<Integer>(cellLength);
List<Integer>arraylist1=newArrayList<Integer>(aryCells.length/2);
intnIndex=0;
intnGSMCellLength=CellLocationManager.this.aryGsmCells.length;
while(nIndex<nGSMCellLength){
//gotoL18
arraylist.add(CellLocationManager.this.aryGsmCells[nIndex]);
nIndex+=2;
}
//gotoL17
nIndex=0;
while(nIndex<aryCells.length){
//gotoL20
arraylist1.add(aryCells[nIndex]);
nIndex+=2;
}
//gotoL19
intnCounter=0;
for(Iterator<Integer>iterator=arraylist.iterator();iterator.hasNext();){
//gotoL22
if(arraylist1.contains(iterator.next()))
nCounter++;
}
//gotoL21
intk4=arraylist.size()-nCounter;
intl4=arraylist1.size()-nCounter;
if(k4+l4>nCounter)
flag=true;
else
flag=false;
if(flag){
StringBuilderstringbuilder=newStringBuilder(k4).append("+");
stringbuilder.append(l4).append(">");
stringbuilder.append(nCounter);
CellLocationManager.this.debug(stringbuilder.toString());
}
break;
}else{
//L15
flag=true;
CellLocationManager.this.debug("PRIMARYCELLCHANGED");
//gotoL14
if(flag){
requestUpdate();
}else{
this.sendEmptyMessageDelayed(MESSAGE_BEFORE_FINISH,CellLocationManager.CHECK_INTERVAL);
}
}
}else{
//L12
flag=true;
//gotoL14
if(flag){
requestUpdate();
}else{
this.sendEmptyMessageDelayed(MESSAGE_BEFORE_FINISH,CellLocationManager.CHECK_INTERVAL);
}
}
}
}
}
}
}
classTaskextendsUserTask<JSONArray,Void,Void>{
intaccuracy;
intbid;
int[]cells;
doublelat;
doublelng;
longtime;
publicTask(int[]aryCell,intbid){
this.time=System.currentTimeMillis();
this.cells=aryCell;
this.bid=bid;
}
publicVoiddoInBackground(JSONArray[]paramArrayOfJSONArray){
try{
JSONObjectjsonObject=newJSONObject();
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");
JSONArraycellJson=paramArrayOfJSONArray[0];
jsonObject.put("cell_towers",cellJson);
JSONArraywifiJson=paramArrayOfJSONArray[1];
jsonObject.put("wifi_towers",wifiJson);
DefaultHttpClientlocalDefaultHttpClient=newDefaultHttpClient();
HttpPostlocalHttpPost=newHttpPost("http://www.google.com/loc/json");
StringstrJson=jsonObject.toString();
StringEntityobjJsonEntity=newStringEntity(strJson);
localHttpPost.setEntity(objJsonEntity);
HttpResponseobjResponse=localDefaultHttpClient.execute(localHttpPost);
intnStateCode=objResponse.getStatusLine().getStatusCode();
HttpEntityhttpEntity=objResponse.getEntity();
byte[]arrayOfByte=null;
if(nStateCode/100==2)
arrayOfByte=EntityUtils.toByteArray(httpEntity);
httpEntity.consumeContent();
StringstrResponse=newString(arrayOfByte,"UTF-8");
jsonObject=newJSONObject(strResponse);
this.lat=jsonObject.getJSONObject("location").getDouble("latitude");
this.lng=jsonObject.getJSONObject("location").getDouble("longitude");
this.accuracy=jsonObject.getJSONObject("location").getInt("accuracy");;
}catch(ExceptionlocalException){
returnnull;
}
returnnull;
}
publicvoidonPostExecute(VoidparamVoid){
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;
StringBuildersb=newStringBuilder("CELLLOCATIONDONE:(");
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);
}
}
}
privateclassCellLocationManagerBroadcastReceiverextendsBroadcastReceiver{
@Override
publicvoidonReceive(Contextarg0,Intentintent){
//access$0state
//1debug
//access$2loop
//3startScanTimestamp
//4disableWifiAfterScan
//5wifimanager
if(CellLocationManager.this.state!=CellLocationManager.STATE_COLLECTING)
return;
Strings=intent.getAction();
if(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(s)){//goto_L4;elsegoto_L3
//_L3:
CellLocationManager.this.debug("WIFISCANCOMPLETE");
CellLocationManager.this.looper.removeMessages(MESSAGE_COLLECTING_WIFI);
longlInterval=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;
Strings1=intent.getAction();
if(!WifiManager.WIFI_STATE_CHANGED_ACTION.equals(s1))
return;
intwifiState=intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,4);
//_L5:
if(wifiState==WifiManager.WIFI_STATE_ENABLING){
booleanflag2=CellLocationManager.this.wifiManager.wifiManager().startScan();
//_L8:
CellLocationManager.this.disableWifiAfterScan=true;
CellLocationManager.this.paused=false;
//inti=flag2?1:0;
//intnDelay=i!=0?8000:0;
//CellLocationManager.this.looper.sendEmptyMessageDelayed(MESSAGE_COLLECTING_WIFI,nDelay);
CellLocationManager.this.debug("WIFIENABLED");
}
}
}
}
}
调用方法:
CellInfoManagercellManager=newCellInfoManager(this);
WifiInfoManagerwifiManager=newWifiInfoManager(this);
CellLocationManagerlocationManager=newCellLocationManager(this,cellManager,wifiManager){
@Override
publicvoidonLocationChanged(){
txtAutoNaviInfo.setText(this.latitude()+"-"+this.longitude());
this.stop();
}
};
locationManager.start();
如果还想同时使用GPS定位,其实也很简单,可以和FourSquare提供的BestLocationListener结合起来,将上面那段代码添加到BestLocationListener的register方法里:
publicvoidregister(LocationManagerlocationManager,booleangps,Contextcontext){
if(DEBUG)Log.d(TAG,"Registeringthislocationlistener:"+this.toString());
longupdateMinTime=SLOW_LOCATION_UPDATE_MIN_TIME;
longupdateMinDistance=SLOW_LOCATION_UPDATE_MIN_DISTANCE;
if(gps){
updateMinTime=LOCATION_UPDATE_MIN_TIME;
updateMinDistance=LOCATION_UPDATE_MIN_DISTANCE;
}
List<String>providers=locationManager.getProviders(true);
intprovidersCount=providers.size();
if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)&&!locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
setChanged();
notifyObservers(null);
}
for(inti=0;i<providersCount;i++){
StringproviderName=providers.get(i);
if(locationManager.isProviderEnabled(providerName)){
updateLocation(locationManager.getLastKnownLocation(providerName));
}
//OnlyregisterwithGPSifwe'veexplicitlyallowedit.
if(gps||!LocationManager.GPS_PROVIDER.equals(providerName)){
locationManager.requestLocationUpdates(providerName,updateMinTime,
updateMinDistance,this);
}
}
if(cellLocationManager==null){
CellInfoManagercellManager=newCellInfoManager(context);
WifiInfoManagerwifiManager=newWifiInfoManager(context);
cellLocationManager=newCellLocationManager(context,cellManager,wifiManager){
@Override
publicvoidonLocationChanged(){
if((latitude()==0.0D)||(longitude()==0.0D))return;
Locationresult=newLocation("CellLocationManager");
result.setLatitude(latitude());
result.setLongitude(longitude());
result.setAccuracy(accuracy());
onBestLocationChanged(result);
this.stop();
}
};
}
//cellLocationManager.stop();
cellLocationManager.start();
//LocationControllercontroller=LocationController.requestLocationUpdates("",updateMinTime,updateMinDistance,this,context);
//controller.requestCurrentLocation();
}