不过其实只要明白了基站/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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
|
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" ); } } } } } |
调用方法:
1
2
3
4
5
6
7
8
9
10
|
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方法里:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
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(); } |