转:android 实现非GPS 手机定位
原理:通过手机读取附近的手机信号基站id ,然后查询google公开的基站数据库获取经纬度。
实现:
通过TelephonyManager 获取lac:mcc:mnc:cell-id (请参考sdk doc文档中TelephonyManager api介绍)
发送到**http://www.google.com/loc/json** 查询
如果不知道lac, mcc,mnc,cell-id ,请Google
google location api 详细 地址http://code.google.com/p/gears/wiki/GeolocationAPI
代码是以前写的简单的例子,(其中函数getNeighboringCellInfo()在android1.5之下是有问题的,返回为空,后者返回无效数据)
- package com.test;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.StringWriter;
- import java.io.UnsupportedEncodingException;
- import java.util.List;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.ClientProtocolException;
- 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.JSONException;
- import org.json.JSONObject;
- import android.app.Activity;
- import android.app.ProgressDialog;
- import android.content.Context;
- import android.content.Intent;
- import android.net.Uri;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- 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;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- public class LocationMe extends Activity implements OnClickListener {
-
/** Called when the activity is first created. */
42. ```
TelephonyManager manager;
TextView tv,loc;
44. ```
int mcc, mnc, lac[] , ci[];
String mac;
46. ```
EditText mcc_text, mnc_text, lac_text, ci_text, mac_text;
Button find,showinmap,update;
48. ```
int count ;
ProgressDialog mProgressDialog;
50. ```
PhoneStateListener listener;
Handler mHandler = new Handler(){
53. ```
@Override
public void handleMessage(Message msg) {
55. ```
if(msg.what==100){
mProgressDialog.dismiss();
57. ```
lac_text.setText(lac[0]+","+lac[1]);//+","+lac[2]);
ci_text.setText(ci[0]+","+ci[1]);//+","+ci[2]);
59. ```
}
if(msg.what==101){
61. ```
tv.setText(result_location);
loc.setText( la + "-" + lo);
63. ```
showinmap.setEnabled(true);
mProgressDialog.dismiss();
65. ```
}
if(msg.what==102){
67. ```
mProgressDialog.dismiss();
}
69. ```
}
};
71. ```
@Override
public void onCreate(Bundle savedInstanceState) {
73. ```
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
75. ```
tv = (TextView) findViewById(R.id.tv);
loc = (TextView) findViewById(R.id.location);
77. ```
mcc_text = (EditText) findViewById(R.id.mcc);
mnc_text = (EditText) findViewById(R.id.mnc);
79. ```
lac_text = (EditText) findViewById(R.id.lac);
ci_text = (EditText) findViewById(R.id.ci);
81. ```
mac_text= (EditText) findViewById(R.id.mac);
find = (Button) findViewById(R.id.find_btn);
83. ```
showinmap = (Button) findViewById(R.id.show_in_map);
manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
85. ```
update= (Button) findViewById(R.id.update);
find.setOnClickListener(this);
88. ```
update.setOnClickListener(this);
showinmap.setOnClickListener(this);
90.
91. ```
ci = new int[10];
lac = new int[10];
93. ```
mProgressDialog =new ProgressDialog(this);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
95. ```
mProgressDialog.setCancelable(false);
listener = new CellStateListener ();
97. ```
}
void update(){
99. ```
count =0;
- // CellLocation location = manager.getCellLocation();
-
Log.e("Location","NetworkCountryIso"+manager.getNetworkCountryIso());//cn
102. ```
mcc = Integer.valueOf(manager.getNetworkOperator().substring(0,3));
mcc_text.setText(String.valueOf(mcc));
104. ```
mnc = Integer.valueOf(manager.getNetworkOperator().substring(3,5));;
mnc_text.setText(String.valueOf(mnc));
106.
107.
108.
109. // manager.listen(listener, PhoneStateListener.LISTEN_CELL_LOCATION);
110. ```
manager.listen(listener, 0);
GsmCellLocation sm = ((GsmCellLocation)manager.getCellLocation());
112. ```
Log.e("Location", "cid"+sm.getCid()+" lac"+sm.getLac());
lac[0]=sm.getLac();
114. // mProgressDialog.setMessage("Updating...(0/3)");
115. // mProgressDialog.show();
116. ```
List<NeighboringCellInfo> list = manager.getNeighboringCellInfo();
count = list.size();
119. ```
Log.e("Location","neighbors "+count);
NeighboringCellInfo info;
121. ```
loc.setText("");
ci_text.setText("");
123. ```
for(int i =0; i<count;i++){
info = list.get(i);
125. ```
Log.e("Location", info.getCid()+"-"+info.getRssi()+" "+info.toString());
lac[i]=lac[0];
127. ```
ci[i]=info.getCid()-415500000;
ci_text.setText(ci_text.getText().toString()+","+ci[i]);
129. ```
loc.setText(loc.getText()+" "+info.getCid());
}
131. ```
}
void findme() {
133. ```
mProgressDialog.setMessage("Finding...");
mProgressDialog.show();
135. ```
Thread thread = new Thread(){
public void run(){
137. ```
try {
DefaultHttpClient client = new DefaultHttpClient();
139.
140. ```
HttpPost post = new HttpPost("[http://www.google.com/loc/json](http://www.google.com/loc/json)");//[http://www.google.com/glm/mmap](http://www.google.com/glm/mmap)");//
JSONObject holder = new JSONObject();
142.
143. ```
holder.put("version", "1.1.0");
- // holder.put("host", "maps.google.com");
- // holder.put("home_mobile_country_code", mcc);
- // holder.put("home_mobile_network_code", mnc);
- // holder.put("radio_type", "gsm");
- // holder.put("carrier", "Vodafone");
-
holder.put("request_address", true);
150. ```
holder.put("address_language", "en-us");
JSONObject data ;// = new JSONObject();
153. // data.put("latitude", 31.244506);
154. // data.put("longitude", 121.591095);
155. // holder.put("location",data);
156.
157. ```
JSONArray array = new JSONArray();
for(int i =0;i<(count<2?count:2);i++){
159. ```
data = new JSONObject();
data.put("cell_id", ci[i]); // 9457, 8321,8243
161. ```
data.put("location_area_code", lac[i]);// 28602
data.put("mobile_country_code", mcc);// 208
163. ```
data.put("mobile_network_code", mnc);// 0
data.put("age", 0);
165. // data.put("signal_strength", -60);
166. // data.put("timing_advance", 5555);
167.
168.
169. ```
array.put(data);
}
171. ```
holder.put("cell_towers", array);
////////////////////////WIFI//////////////////////////////////////
174. // WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
175. // WifiInfo info = wm.getConnectionInfo();
176. // String mac = info.getMacAddress();
177. // Log.e("LocationMe","mac:"+mac);
178. // data = new JSONObject();
179. // data.put("mac_address", mac);
180. // data.put("signal_strength", 8);
181. // data.put("age", 0);
182. // array = new JSONArray();
183. // array.put(data);
184. ```
//holder.put("wifi_towers ", array);
////////////////////////////////////
186.
187.
188.
189.
190. ```
StringEntity se = new StringEntity(holder.toString());
Log.e("Location send",holder.toString());
192. ```
post.setEntity(se);
HttpResponse resp = client.execute(post);
194.
195. ```
HttpEntity entity = resp.getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(entity
198. ```
.getContent()));
StringBuffer sb = new StringBuffer();
200. ```
String result = br.readLine();
while (result != null) {
202. ```
Log.e("Locaiton reseive", result);
sb.append(result);
204. ```
result = br.readLine();
}
206. ```
result_location = sb.toString();
data = new JSONObject(sb.toString());
210. ```
data = (JSONObject) data.get("location");
la = (Double) data.get("latitude");
212. ```
lo = (Double) data.get("longitude");
mHandler.sendEmptyMessage(101);
214. ```
} catch (ClientProtocolException e) {
e.printStackTrace();
216. ```
mHandler.sendEmptyMessage(102);
} catch (IOException e) {
218. ```
e.printStackTrace();
mHandler.sendEmptyMessage(102);
220. ```
} catch (JSONException e) {
e.printStackTrace();
222. // loc.setText("");
223. // showinmap.setEnabled(false);
224. ```
mHandler.sendEmptyMessage(102);
}
226. ```
}
};
228. ```
thread.start();
}
231.
232.
233. ```
String result_location;
double la,lo;
235. ```
@Override
public void onClick(View arg0) {
237. ```
switch(arg0.getId()){
case R.id.find_btn:{
239. ```
findme();
break;
241. ```
}
case R.id.show_in_map:{
243. ```
Uri mapUri = Uri.parse("geo:"+la+","+lo+"?z=12&cbp=1");
startActivity(new Intent(Intent.ACTION_VIEW, mapUri));
245. ```
break;
}
247. ```
case R.id.update:{
update();
249. ```
break;
}
251.
252. ```
}
}
255. ```
class CellStateListener extends PhoneStateListener{
public void onCellLocationChanged(CellLocation location){
257. ```
GsmCellLocation gsmL = (GsmCellLocation) location;
if(count <2){
259. ```
ci[count] = gsmL.getCid();
lac[count] = gsmL.getLac();
261. ```
count++;
mProgressDialog.setMessage("Updating...("+count+"/3)");
263. ```
gsmL.requestLocationUpdate();
if(count ==2){
265. ```
manager.listen(this, 0);
mHandler.sendEmptyMessage(100);
267. ```
}
}
269.
270.
271. ```
}
}
273. }
274.
275. /*
276. Gears Request
277.
278.
279. {
280. "version": "1.1.0",
281. "host": "maps.google.com",
282. "access_token": "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe",
283. "home_mobile_country_code": 310,
284. "home_mobile_network_code": 410,
285. "radio_type": "gsm",
286. "carrier": "Vodafone",
287. "request_address": true,
288. "address_language": "en_GB",
289. "location": {
290. ```
"latitude": 51.0,
"longitude": -0.1
292. },
293. "cell_towers": [
294. ```
{
"cell_id": 42,
296. ```
"location_area_code": 415,
"mobile_country_code": 310,
298. ```
"mobile_network_code": 410,
"age": 0,
300. ```
"signal_strength": -60,
"timing_advance": 5555
302. ```
},
{
304. ```
"cell_id": 88,
"location_area_code": 415,
306. ```
"mobile_country_code": 310,
"mobile_network_code": 580,
308. ```
"age": 0,
"signal_strength": -70,
310. ```
"timing_advance": 7777
}
312. ],
313. "wifi_towers": [
314. ```
{
"mac_address": "01-23-45-67-89-ab",
316. ```
"signal_strength": 8,
"age": 0
318. ```
},
{
320. ```
"mac_address": "01-23-45-67-89-ac",
"signal_strength": 4,
322. ```
"age": 0
}
324. ]
325. }
326.
327.
328. * responce
329. {
330. "location": {
331. ```
"latitude": 51.0,
"longitude": -0.1,
333. ```
"altitude": 30.1,
"accuracy": 1200.4,
335. ```
"altitude_accuracy": 10.6,
"address": {
337. ```
"street_number": "100",
"street": "Amphibian Walkway",
339. ```
"postal_code": "94043",
"city": "Mountain View",
341. ```
"county": "Mountain View County",
"region": "California",
343. ```
"country": "United States of America",
"country_code": "US"
345. ```
}
- },
- "access_token": "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe"
- }
- 08-03 16:48:08.393: ERROR/Location(2350): NetworkCountryIsocn
- 08-03 16:48:08.423: ERROR/Location(2350): cid9457 lac6340
- 08-03 16:48:08.443: ERROR/Location(2350): neighbors 5
- 08-03 16:48:08.453: ERROR/Location(2350): 415506483-9 [18c42033 at 9]
- 08-03 16:48:08.463: ERROR/Location(2350): 415506691-9 [18c42103 at 9]
- 08-03 16:48:08.463: ERROR/Location(2350): 415506529-7 [18c42061 at 7]
- 08-03 16:48:08.473: ERROR/Location(2350): 415531363-11 [18c48163 at 11]
- 08-03 16:48:08.483: ERROR/Location(2350): 415506531-6 [18c42063 at 6]
-
- */