Android地位的4大方式
2016-07-13 16:40
447 查看
开发中对于地图及地理位置的定位是我们经常要用地,地图功能的使用使得我们应用功能更加完善,下面总结了一下网络中现有对于介绍android定位的4种方式,希望对大家有帮助:
android 定位一般有四种方法,这四种方式分别是:GPS定位,WIFI定准,基站定位,AGPS定位
(1)Android GPS
需要GPS硬件支持,直接和卫星交互来获取当前经纬度,这种方式需要手机支持GPS模块(现在大部分的智能机应该都有了)。通过GPS方式准确度是最高的,但是它的缺点也非常明显:1,比较耗电;2,绝大部分用户默认不开启GPS模块;3,从GPS模块启动到获取第一次定位数据,可能需要比较长的时间;4,室内几乎无法使用。这其中,缺点2,3都是比较致命的。需要指出的是,GPS走的是卫星通信的通道,在没有网络连接的情况下也能用。
要实用Adnroid平台的GPS设备,首先需要添加上权限,所以需要添加如下权限:
[plain] view plain copy
uses-permission android:name= android.permission.ACCESS_FINE_LOCATION /uses-permission
具体实现代码如下:
首先判断GPS模块是否存在或者是开启:
如果开启正常,则会直接进入到显示页面,如果开启不正常,则会进行到GPS设置页面:
获取代码如下:
(2)Android 基站定位
Android 基站定位只要明白了基站/WIFI定位的原理,自己实现基站/WIFI定位其实不难。基站定位一般有几种,第一种是利用手机附近的三个基站进行三角定位,由于每个基站的位置是固定的,利用电磁波在这三个基站间中转所需要时间来算出手机所在的坐标;第二种则是利用获取最近的基站的信息,其中包括基站 id,location area code、mobile country code、mobile network code和信号强度,将这些数据发送到google的定位web服务里,就能拿到当前所在的位置信息,误差一般在几十米到几百米之内。其中信号强度这个数据很重要。
Android基站的具体位置获取,代码如下:
所需权限代码如下:
[html] view plain copy
(3)Android Wifi定位
根据一个固定的WifiMAC地址,通过收集到的该Wifi热点的位置,然后访问网络上的定位服务以获得经纬度坐标,原理也和基站定位一样,必须要拿到WIFI路由器的SSID和信号强度。因为它和基站定位其实都需要使用网络,所以在Android也统称为Network方式。
上面是取到WIFI的mac地址的方法,下面是把地址发送给google服务器,代码如下
3.1 WIFI定位与基站定位的结合
有些用户默认是将WIFI关闭的,通过API开启WIFI硬件并进行搜索附近的WIFI路由器需要一段时间,怎样才能将手机基站定位和WIFI定位完美结合起来呢,Android提供了一种很好的机制,就是Handler和Looper,Handler和Looper一般用于跨线程传递数据,但当在单线程里使用时,就变成了一个先进先出的消息泵。利用这个消息泵进行调度,就可以将基站定位和WIFI定位完美结合。以下是相关的代码:
调用方法:
如果还想同时使用GPS定位,其实也很简单,可以和FourSquare提供的BestLocationListener结合起来,将上面那段代码添加到BestLocationListener的register方法里:
AGPS定位
AGPS(AssistedGPS:辅助全球卫星定位系统)是结合GSM或GPRS与传统卫星定位,利用基地台代送辅助卫星信息,以缩减GPS芯片获取卫星信号的延迟时间,受遮盖的室内也能借基地台讯号弥补,减轻GPS芯片对卫星的依赖度。和纯GPS、基地台三角定位比较,AGPS能提供范围更广、更省电、速度更快的定位服务,理想误差范围在10公尺以内,日本和美国都已经成熟运用AGPS于LBS服务(Location Based Service,基于位置的服务)。AGPS技术是一种结合了网络基站信息和GPS信息对移动台进行定位的技术,可以在GSM/GPRS、WCDMA和CDMA2000网络中使进行用。该技术需要在手机内增加GPS接收机模块,并改造手机的天线,同时要在移动网络上加建位置服务器、差分GPS基准站等设备。手机可以通过网络(通常为GPRS)获得即时GPS星历数据,让GPS更快完成定位,定位完成后,AGPS就可以不用了。AGPS解决方案的优势主要体现在其定位精度上,该技术的另一优点为:使用AGPS后,TTFF可以缩短三分之二,一般10秒左右即可定位。
TTFF:Time To First Fix,首次定位时间,这是衡量GPS芯片定位能力的重要参数,严格意义来说,这是没有AGPS时冷启动(清除了GPS内存中所有的数据)后完成首次定位需要的时间,正常为40-60秒左右。
android 定位一般有四种方法,这四种方式分别是:GPS定位,WIFI定准,基站定位,AGPS定位
(1)Android GPS
需要GPS硬件支持,直接和卫星交互来获取当前经纬度,这种方式需要手机支持GPS模块(现在大部分的智能机应该都有了)。通过GPS方式准确度是最高的,但是它的缺点也非常明显:1,比较耗电;2,绝大部分用户默认不开启GPS模块;3,从GPS模块启动到获取第一次定位数据,可能需要比较长的时间;4,室内几乎无法使用。这其中,缺点2,3都是比较致命的。需要指出的是,GPS走的是卫星通信的通道,在没有网络连接的情况下也能用。
要实用Adnroid平台的GPS设备,首先需要添加上权限,所以需要添加如下权限:
[plain] view plain copy
uses-permission android:name= android.permission.ACCESS_FINE_LOCATION /uses-permission
具体实现代码如下:
首先判断GPS模块是否存在或者是开启:
[java] view plain copy private voidopenGPSSettings() { LocationManager alm = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE); if (alm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) { Toast.makeText(this, GPS模块正常 ,Toast.LENGTH_SHORT) .show(); return; } Toast.makeText(this, 请开启GPS! ,Toast.LENGTH_SHORT).show(); Intent intent = newIntent(Settings.ACTION_SECURITY_SETTINGS); startActivityForResult(intent,0); //此为设置完成后返回到获取界面 }
如果开启正常,则会直接进入到显示页面,如果开启不正常,则会进行到GPS设置页面:
获取代码如下:
[java] view plain copy private voidgetLocation() { // 获取位置管理服务 LocationManager locationManager; String serviceName = Context.LOCATION_SERVICE; locationManager = (LocationManager)this.getSystemService(serviceName); // 查找到服务信息 Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); // 高精度 criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); // 低功耗 String provider =locationManager.getBestProvider(criteria, true); // 获取GPS信息 Location location =locationManager.getLastKnownLocation(provider); // 通过GPS获取位置 updateToNewLocation(location); // 设置监听*器,自动更新的最小时间为间隔N秒(1秒为1*1000,这样写主要为了方便)或最小位移变化超过N米 locationManager.requestLocationUpdates(provider,100 * 1000, 500,locationListener); } 到这里就可以获取到地理位置信息了,但是还是要显示出来,那么就用下面的方法进行显示: [java] view plain copy private voidupdateToNewLocation(Location location) { TextView tv1; tv1 = (TextView)this.findViewById(R.id.tv1); if (location != null) { double latitude = location.getLatitude(); double longitude=location.getLongitude(); tv1.setText( 维度: + latitude+ \n经度 +longitude); } else { tv1.setText( 无法获取地理信息 ); } }
(2)Android 基站定位
Android 基站定位只要明白了基站/WIFI定位的原理,自己实现基站/WIFI定位其实不难。基站定位一般有几种,第一种是利用手机附近的三个基站进行三角定位,由于每个基站的位置是固定的,利用电磁波在这三个基站间中转所需要时间来算出手机所在的坐标;第二种则是利用获取最近的基站的信息,其中包括基站 id,location area code、mobile country code、mobile network code和信号强度,将这些数据发送到google的定位web服务里,就能拿到当前所在的位置信息,误差一般在几十米到几百米之内。其中信号强度这个数据很重要。
Android基站的具体位置获取,代码如下:
[java] view plain copy import java.io.BufferedReader; import java.io.InputStreamReader; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONObject; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.telephony.TelephonyManager; import android.telephony.gsm.GsmCellLocation; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; public class Test extends Activity { Context context=this; LinearLayout mainView=null; Button button=null; TextView tv=null; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setTitle("基站+联网+google数据库定位"); mainView=new LinearLayout(this); mainView.setOrientation(LinearLayout.VERTICAL); button=new Button(this); button.setText("定位测试"); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { (new HttpThread(context)).start(); } }); mainView.addView(button,new LinearLayout.LayoutParams(-2,-2)); tv=new TextView(this); tv.setText("Hello!\n"); mainView.addView(tv); setContentView(mainView); } class HttpThread extends Thread { TelephonyManager tm=null; GsmCellLocation gcl=null; int cid=0; int lac=0; int mcc = 0; int mnc =0; StringBuffer sb=null; Handler handler=new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case 1: tv.append(sb.toString()); break; } super.handleMessage(msg); } }; HttpThread(Context context) { tm=(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); gcl=(GsmCellLocation) tm.getCellLocation(); cid=gcl.getCid(); lac=gcl.getLac(); mcc = Integer.valueOf(tm.getNetworkOperator().substring(0,3)); mnc = Integer.valueOf(tm.getNetworkOperator().substring(3,5)); sb=new StringBuffer(); sb.append("cid:"+cid + "\n"); sb.append("lac:"+lac + "\n"); sb.append("mcc:"+mcc + "\n"); sb.append("mnc:"+mnc + "\n"); } public void run() { try { JSONObject jObject = new JSONObject(); jObject.put("version", "1.1.0"); jObject.put("host", "maps.google.com"); jObject.put("request_address", true); if (mcc == 460) { jObject.put("address_language", "zh_CN"); } else { jObject.put("address_language", "en_US"); } JSONArray jArray = new JSONArray(); JSONObject jData = new JSONObject(); jData.put("cell_id", cid); jData.put("location_area_code", lac); jData.put("mobile_country_code", mcc); jData.put("mobile_network_code", mnc); jArray.put(jData); jObject.put("cell_towers", jArray); DefaultHttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost("http://www.google.com/loc/json"); StringEntity se = new StringEntity(jObject.toString()); post.setEntity(se); HttpResponse resp = client.execute(post); BufferedReader br = null; if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { sb.append("联网成功\n"); br = new BufferedReader(new InputStreamReader(resp.getEntity().getContent())); } else { sb.append("联网获取数据失败!\n"); } String result = br.readLine(); while (result != null) { sb.append(result); result = br.readLine(); } } catch(Exception ex) { sb.append(ex.getMessage()); } Message msg=new Message(); msg.what=1; handler.sendMessage(msg); } } }
所需权限代码如下:
[html] view plain copy
<uses-permission android:name="android.permission.INTERNET"></uses-permission> < uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
(3)Android Wifi定位
根据一个固定的WifiMAC地址,通过收集到的该Wifi热点的位置,然后访问网络上的定位服务以获得经纬度坐标,原理也和基站定位一样,必须要拿到WIFI路由器的SSID和信号强度。因为它和基站定位其实都需要使用网络,所以在Android也统称为Network方式。
[java] view plain copy public classWiFiInfoManager implements Serializable { private static final long serialVersionUID= -4582739827003032383L; private Context context; public WiFiInfoManager(Context context) { super(); this.context = context; } public WifiInfo getWifiInfo() { WifiManager manager = (WifiManager)context .getSystemService(Context.WIFI_SERVICE); WifiInfo info = new WifiInfo(); info.mac =manager.getConnectionInfo().getBSSID(); Log.i( TAG , WIFI MACis: + info.mac); return info; } public class WifiInfo { public String mac; public WifiInfo() { super(); } } }
上面是取到WIFI的mac地址的方法,下面是把地址发送给google服务器,代码如下
[java] view plain copy public staticLocation getWIFILocation(WifiInfo wifi) { if (wifi == null) { Log.i( TAG , wifiis null. ); return null; } DefaultHttpClient client = newDefaultHttpClient(); HttpPost post = new HttpPost( http://www.google.com/loc/json ); JSONObject holder = new JSONObject(); try { holder.put( version , 1.1.0 ); holder.put( host , maps.google.com ); JSONObject data; JSONArray array = new JSONArray(); if (wifi.mac != null wifi.mac.trim().length() 0) { data = new JSONObject(); data.put( mac_address , wifi.mac); data.put( signal_strength , 8); data.put( age , 0); array.put(data); } holder.put( wifi_towers ,array); Log.i( TAG , request json: + holder.toString()); StringEntity se = newStringEntity(holder.toString()); post.setEntity(se); HttpResponse resp =client.execute(post); int state =resp.getStatusLine().getStatusCode(); if (state == HttpStatus.SC_OK) { HttpEntity entity =resp.getEntity(); if (entity != null) { BufferedReader br = newBufferedReader( newInputStreamReader(entity.getContent())); StringBuffer sb = newStringBuffer(); String resute = ; while ((resute =br.readLine()) != null) { sb.append(resute); } br.close(); Log.i( TAG , response json: + sb.toString()); data = newJSONObject(sb.toString()); data = (JSONObject)data.get( location ); Location loc = newLocation( android.location.LocationManager.NETWORK_PROVIDER); loc.setLatitude((Double)data.get( latitude )); loc.setLongitude((Double)data.get( longitude )); loc.setAccuracy(Float.parseFloat(data.get( accuracy ) .toString())); loc.setTime(System.currentTimeMillis()); return loc; } else { return null; } } else { Log.v( TAG , state + ); return null; } } catch (Exception e) { Log.e( TAG ,e.getMessage()); return null; } }
3.1 WIFI定位与基站定位的结合
有些用户默认是将WIFI关闭的,通过API开启WIFI硬件并进行搜索附近的WIFI路由器需要一段时间,怎样才能将手机基站定位和WIFI定位完美结合起来呢,Android提供了一种很好的机制,就是Handler和Looper,Handler和Looper一般用于跨线程传递数据,但当在单线程里使用时,就变成了一个先进先出的消息泵。利用这个消息泵进行调度,就可以将基站定位和WIFI定位完美结合。以下是相关的代码:
CellInfoManager [java] view plain copy 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 ; 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; } } }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 ; 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 [java] view plain copy 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 [java] view plain copy 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"); } } } } }
调用方法:
[java] view plain copy 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方法里:
[java] view plain copy 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(); }
AGPS定位
AGPS(AssistedGPS:辅助全球卫星定位系统)是结合GSM或GPRS与传统卫星定位,利用基地台代送辅助卫星信息,以缩减GPS芯片获取卫星信号的延迟时间,受遮盖的室内也能借基地台讯号弥补,减轻GPS芯片对卫星的依赖度。和纯GPS、基地台三角定位比较,AGPS能提供范围更广、更省电、速度更快的定位服务,理想误差范围在10公尺以内,日本和美国都已经成熟运用AGPS于LBS服务(Location Based Service,基于位置的服务)。AGPS技术是一种结合了网络基站信息和GPS信息对移动台进行定位的技术,可以在GSM/GPRS、WCDMA和CDMA2000网络中使进行用。该技术需要在手机内增加GPS接收机模块,并改造手机的天线,同时要在移动网络上加建位置服务器、差分GPS基准站等设备。手机可以通过网络(通常为GPRS)获得即时GPS星历数据,让GPS更快完成定位,定位完成后,AGPS就可以不用了。AGPS解决方案的优势主要体现在其定位精度上,该技术的另一优点为:使用AGPS后,TTFF可以缩短三分之二,一般10秒左右即可定位。
TTFF:Time To First Fix,首次定位时间,这是衡量GPS芯片定位能力的重要参数,严格意义来说,这是没有AGPS时冷启动(清除了GPS内存中所有的数据)后完成首次定位需要的时间,正常为40-60秒左右。
相关文章推荐
- Android界面编程——导航栏及菜单(六)
- android addContentView视图后的移除
- Android Force Close和ANR等异常处理方法
- android 工具类方法传入Context导致Activity内存泄漏
- android webview 适配html页面
- 设置的JMeter 2.6在Mac
- Android开发——常用ADB命令的使用
- [置顶] android音乐播放器开发在线加载歌词
- Android开发——常用ADB命令的使用
- SSH方式连接Android设备
- 在windows上下载安装Android sdk
- 安卓学习笔记---AndroidStudio快捷键
- (15.1.19)我的 Android 开发实战经验总结
- Android Settings(系统设置)源码分析(一)
- android 设定activity的进入和退出效果
- Android自定义开关(可滑动,点击)
- (4.6.18)Android编码命名规范
- Android崩溃异常捕获方法
- Android查询/设置Settings的值
- 一次UsageStatsManager在UTC零点清零数据的Debug