android定位之基站的定位(含GSM与cdma实现源码)
GPS定位能提供精确, 详细的数据。但是有的时候我们不能通过GPS获得数据,如在屋子里面,无GPS功能等情况。那我们就需要其他的定位手段,基站定位是一个不错的选择。
当我们手机开机时,手机会自动向信号最强的无线通讯台联系,注册信息,这个通讯台就是我们所说的基站,每个基站都有自己的id,我们通过这个基站的id能够找到基站的位置,而国内城市的基站密度可以达到500米以下或者更低,所以能够大体上确定我们的位置。
必备知识:
1. TelephonyManager: 主要提供了一系列用于访问与手机通讯相关的状态和信息的get方法。其中包括手机SIM的状态和信息、电信网络的状态及手机用户的信息。在这里我们就是通过这个类获得基站信息。
2. GsmCellLocation:装载着从TelephonyManager中获得的信息。
3. JSONObject,JSONArray:组建json相关的类。
4. 联网相关的类。
代码步骤:1.启动按钮和画板
2.获得基站信息
3.创建json
4. 创建连接,发送请求并接受回应
5. 获得数据
6、进行权限申请:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
具体代码实现: 以下代码,复制到项目即可运行!
Java源码:
package cn.LocationStation;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Date;
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.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class LocationStation extends Activity {
TextView mTextView;
Button mButton;
TelephonyManager tm;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView = (TextView) findViewById(R.id.textView001);
mButton = (Button) findViewById(R.id.Button001);
tm = (TelephonyManager) this
.getSystemService(Context.TELEPHONY_SERVICE);
mButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
GsmCellLocation gcl = (GsmCellLocation) tm.getCellLocation();
int cid = gcl.getCid();
int lac = gcl.getLac();
int mcc = Integer.valueOf(tm.getNetworkOperator().substring(0,
3));
int mnc = Integer.valueOf(tm.getNetworkOperator().substring(3,
5));
try {
// 组装JSON查询字符串
JSONObject holder = new JSONObject();
holder.put("version", "1.1.0");
holder.put("host", "maps.google.com");
// holder.put("address_language", "zh_CN");
holder.put("request_address", true);
JSONArray array = new JSONArray();
JSONObject data = new JSONObject();
data.put("cell_id", cid); // 25070
data.put("location_area_code", lac);// 4474
data.put("mobile_country_code", mcc);// 460
data.put("mobile_network_code", mnc);// 0
array.put(data);
holder.put("cell_towers", array);
// 创建连接,发送请求并接受回应
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(
"http://www.google.com/loc/json");
StringEntity se = new StringEntity(holder.toString());
post.setEntity(se);
HttpResponse resp = client.execute(post);
HttpEntity entity = resp.getEntity();
BufferedReader br = new BufferedReader(
new InputStreamReader(entity.getContent()));
StringBuffer sb = new StringBuffer();
String result = br.readLine();
while (result != null) {
sb.append(result);
result = br.readLine();
}
JSONObject jsonObject = new JSONObject(sb.toString());
JSONObject jsonObject1 = new JSONObject(jsonObject
.getString("location"));
getAddress(jsonObject1.getString("latitude"), jsonObject1
.getString("longitude"));
//mTextView.setText(sb.toString());
} catch (Exception e) {
// TODO: handle exception
}
}
});
}
void getAddress(String lat, String lag) {
try {
URL url = new URL("http://maps.google.cn/maps/geo?key=abcdefg&q="
+ lat + "," + lag);
InputStream inputStream = url.openConnection().getInputStream();
InputStreamReader inputReader = new InputStreamReader(inputStream,
"utf-8");
BufferedReader bufReader = new BufferedReader(inputReader);
String line = "", lines = "";
while ((line = bufReader.readLine()) != null) {
lines += line;
}
if (!lines.equals("")) {
JSONObject jsonobject = new JSONObject(lines);
JSONArray jsonArray = new JSONArray(jsonobject.get("Placemark")
.toString());
for (int i = 0; i < jsonArray.length(); i++) {
mTextView.setText(mTextView.getText() + "\n"
+ jsonArray.getJSONObject(i).getString("address"));
}
}
} catch (Exception e) {
;
}
}
}
xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:id="@+id/Button001" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/hello" />
<TextView android:id="@+id/textView001" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/hello" />
</LinearLayout>
androidmanifest文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.LocationStation"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".LocationStation"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.PERMISSION_NAME"></uses-permission>
</manifest>
对于CDMA基站定位:
-
Java code
-
public void onClick(View v) { // TODO Auto-generated method stub tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); // int type = tm.getNetworkType(); // if (type ==TelephonyManager.NETWORK_TYPE_CDMA) { location = (CdmaCellLocation) tm.getCellLocation(); if (location == null ) return ; int sid = location.getSystemId(); // 系统标识 mobileNetworkCode int bid = location.getBaseStationId(); // 基站小区号 cellId int nid = location.getNetworkId(); // 网络标识 locationAreaCode Log.i(\ " sid:\", \"\" + sid); Log.i(\ " bid:\", \"\" + bid); Log.i(\ " nid:\", \"\" + nid); ArrayList < CellIDInfo > CellID = new ArrayList < CellIDInfo > (); CellIDInfo info = new CellIDInfo(); info.cellId = bid; info.locationAreaCode = nid; info.mobileNetworkCode = String.valueOf(sid); info.mobileCountryCode = tm.getNetworkOperator().substring( 0 , 3 ); info.mobileCountryCode = tm.getNetworkOperator().substring( 3 , 5 ); info.radioType = \ " cdma\"; CellID.add(info); Log.d(\ " cellId:\", \"\" + info.cellId); Log.d(\ " locationAreaCode:\", \"\" + info.locationAreaCode); Log.d(\ " mobileNetworkCode:\", info.mobileNetworkCode); Log.d(\ " mobileCountryCode:\", info.mobileCountryCode); Location loc = callGear(CellID); if (loc != null ) mTextView.setText(\ " 纬度:\" + loc.getLatitude() + \"\\n经度:\" + loc.getLongitude()); // } // end if } // end onclick
调用google gears的方法,该方法调用gears来获取经纬度 代码:
-
Java code
-
// 调用google gears的方法,该方法调用gears来获取经纬度 private Location callGear(ArrayList < CellIDInfo > cellID) { if (cellID == null ) return null ; DefaultHttpClient client = new DefaultHttpClient(); 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\"); holder.put(\ " home_mobile_country_code\", cellID.get(0).mobileCountryCode); holder.put(\ " home_mobile_network_code\", cellID.get(0).mobileNetworkCode); holder.put(\ " radio_type\", cellID.get(0).radioType); holder.put(\ " request_address\", true); if (\ " 460\".equals(cellID.get(0).mobileCountryCode)) holder.put(\ " address_language\", \"zh_CN\"); else holder.put(\ " address_language\", \"en_US\"); JSONObject data,current_data; JSONArray array = new JSONArray(); current_data = new JSONObject(); current_data.put(\ " cell_id\", cellID.get(0).cellId); current_data.put(\ " location_area_code\", cellID.get(0).locationAreaCode); current_data.put(\ " mobile_country_code\", cellID.get(0).mobileCountryCode); current_data.put(\ " mobile_network_code\", cellID.get(0).mobileNetworkCode); current_data.put(\ " age\", 0); current_data.put(\ " signal_strength\", -60); current_data.put(\ " timing_advance\", 5555); array.put(current_data); holder.put(\ " cell_towers\", array); StringEntity se = new StringEntity(holder.toString()); Log.e(\ " Location send\", holder.toString()); post.setEntity(se); HttpResponse resp = client.execute(post); HttpEntity entity = resp.getEntity(); BufferedReader br = new BufferedReader( new InputStreamReader(entity.getContent())); StringBuffer sb = new StringBuffer(); String result = br.readLine(); while (result != null ) { Log.e(\ " Locaiton reseive\", result); sb.append(result); result = br.readLine(); } data = new JSONObject(sb.toString()); Log.d(\ " -\", sb.toString()); data = (JSONObject) data.get(\ " location\"); Location loc = new 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()); // AppUtil.getUTCTime()); return loc; } catch (JSONException e) { e.printStackTrace(); return null ; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Log.d(\ " -\", \"null 1\"); return null ; }
在弄这个的时候不要忘了加权限噢!
-
Java code
-
< uses - permission android:name = \ " android.permission.ACCESS_COARSE_LOCATION\"></uses-permission> < uses - permission android:name = \ " android.permission.READ_PHONE_STATE\"></uses-permission> < uses - permission android:name = \ " android.permission.INTERNET\"></uses-permission>
关键代码:
- telephonyManager =(TelephonyManager)getSystemService(TELEPHONY_SERVICE);
- myCDMACellLoc = (CdmaCellLocation)telephonyManager.getCellLocation();
- double lat = (double)myCDMACellLoc.getBaseStationLatitude() /14400;
- double lon = (double)myCDMACellLoc.getBaseStationLongitude() /14400;
程序只是测试用,尚不完善!希望这个东东对需要的朋友有用!有什么不对的地方请大家指点指点。