关于定位原理网上很多,这里就不多说了。下面说怎么实现的,直接贴代码如下:
首先是Util类:
import java.io.BufferedReader; import java.io.InputStreamReader; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONObject; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.util.Log; public class Util { //log的标签 public static final String TAG = "location"; public static final boolean DEBUG = true; public static final String LOCATION_URL = "http://www.google.com/loc/json"; public static final String LOCATION_HOST = "maps.google.com"; public static void logi(String content){ if(DEBUG) { Log.i(TAG, content); } } public static void loge(String content){ if(DEBUG) { Log.e(TAG, content); } } public static void logd(String content){ if(DEBUG) { Log.d(TAG, content); } } /** * 获取地理位置 * * @throws Exception */ public static String getLocation(String latitude, String longitude) throws Exception { String resultString = ""; /** 这里采用get方法,直接将参数加到URL上 */ String urlString = String.format("http://maps.google.cn/maps/geo?key=abcdefg&q=%s,%s", latitude, longitude); Util.logi("Util: getLocation: URL: " + urlString); /** 新建HttpClient */ HttpClient client = new DefaultHttpClient(); /** 采用GET方法 */ HttpGet get = new HttpGet(urlString); try { /** 发起GET请求并获得返回数据 */ HttpResponse response = client.execute(get); HttpEntity entity = response.getEntity(); BufferedReader buffReader = new BufferedReader(new InputStreamReader(entity.getContent())); StringBuffer strBuff = new StringBuffer(); String result = null; while ((result = buffReader.readLine()) != null) { strBuff.append(result); } resultString = strBuff.toString(); /** 解析JSON数据,获得物理地址 */ if (resultString != null && resultString.length() > 0) { JSONObject jsonobject = new JSONObject(resultString); JSONArray jsonArray = new JSONArray(jsonobject.get("Placemark").toString()); resultString = ""; for (int i = 0; i < jsonArray.length(); i++) { resultString = jsonArray.getJSONObject(i).getString("address"); } } } catch (Exception e) { throw new Exception("获取物理位置出现错误:" + e.getMessage()); } finally { get.abort(); client = null; } return resultString; } /** * 判断网络是否可用 * @param context * @return */ public static boolean isNetworkAvaliable(Context context){ ConnectivityManager manager = (ConnectivityManager) (context .getSystemService(Context.CONNECTIVITY_SERVICE)); NetworkInfo networkinfo = manager.getActiveNetworkInfo(); return !(networkinfo == null || !networkinfo.isAvailable()); } /** * 判断网络类型 wifi 3G * * @param context * @return */ public static boolean isWifiNetwrokType(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = connectivityManager.getActiveNetworkInfo(); if (info != null && info.isAvailable()) { if (info.getTypeName().equalsIgnoreCase("wifi")) { return true; } } return false; } }
在MainActivity中根据当前网络环境,决定用WIFI定位还是基站定位
import com.demo.location.cell.CellLocationManager; import com.demo.location.wifi.WifiLocationManager; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private TextView mTextView; private Button mButton; private WifiLocationManager wifiLocation; private CellLocationManager cellLocation; /** 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.tv_show_info); mButton = (Button) findViewById(R.id.btn_get_info); wifiLocation = new WifiLocationManager(MainActivity.this); cellLocation = new CellLocationManager(MainActivity.this); mButton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub Util.logi("MainActivity: on mButton Click!!!"); getLocation(); } }); } private void getLocation(){ boolean isNet = Util.isNetworkAvaliable(MainActivity.this); if(!isNet){ Toast.makeText(MainActivity.this, "网络不可用:打开WIFI 或 数据连接!!!", Toast.LENGTH_LONG).show(); Util.logd("MainActivity: getLocation: Net work is not avaliable, and return!!!"); return; } boolean isWifi = Util.isWifiNetwrokType(MainActivity.this); if(isWifi){ Util.logd("MainActivity: getLocation: Wifi定位"); wifiLocation.getLocation(new WifiReceiver()); }else{ Util.logd("MainActivity: getLocation: 基站定位"); String location = cellLocation.getLocationCell(); mTextView.setText(location); } } class WifiReceiver extends BroadcastReceiver { public void onReceive(Context c, Intent intent) { Util.logi("get broadcastReceiver: SCAN_RESULTS_AVAILABLE_ACTION"); String location = wifiLocation.getLocationWifi(); mTextView.setText(location); } } }
1. WIFI定位:
WIFI定位的实现在WifiLocationManager.java里
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; 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.HttpClient; 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 com.demo.location.Util; import android.content.BroadcastReceiver; import android.content.Context; import android.content.IntentFilter; import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; public class WifiLocationManager { private Context mContext; private WifiManager wifiManager; public WifiLocationManager(Context context){ mContext = context; wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); } public void getLocation(BroadcastReceiver receiver){ mContext.registerReceiver(receiver, new IntentFilter( WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); wifiManager.startScan(); } public List<ScanResult> getWifiList(){ return wifiManager.getScanResults(); } public String getLocationWifi(){ /** 采用Android默认的HttpClient */ HttpClient client = new DefaultHttpClient(); /** 采用POST方法 */ HttpPost post = new HttpPost(Util.LOCATION_URL); try { /** 构造POST的JSON数据 */ JSONObject holder = new JSONObject(); holder.put("version", "1.1.0"); holder.put("host", Util.LOCATION_HOST); holder.put("address_language", "zh_CN"); holder.put("request_address", true); JSONArray towerarray = new JSONArray(); List<ScanResult> wifiList = getWifiList(); for (int i = 0; i < wifiList.size(); i++) { JSONObject tower = new JSONObject(); tower.put("mac_address", wifiList.get(i).BSSID); tower.put("ssid", wifiList.get(i).SSID); tower.put("signal_strength", wifiList.get(i).level); towerarray.put(tower); } holder.put("wifi_towers", towerarray); Util.logd("holder.put: " + holder.toString()); StringEntity query = new StringEntity(holder.toString()); post.setEntity(query); /** 发出POST数据并获取返回数据 */ HttpResponse response = client.execute(post); HttpEntity entity = response.getEntity(); BufferedReader buffReader = new BufferedReader(new InputStreamReader(entity.getContent())); StringBuffer strBuff = new StringBuffer(); String result = null; while ((result = buffReader.readLine()) != null) { strBuff.append(result); } Util.logd("result: " + strBuff.toString()); /** 解析返回的JSON数据获得经纬度 */ JSONObject json = new JSONObject(strBuff.toString()); JSONObject subjosn = new JSONObject(json.getString("location")); String latitude = subjosn.getString("latitude"); String longitude = subjosn.getString("longitude"); return Util.getLocation(latitude, longitude); } catch(ClientProtocolException e){ Util.loge("ClientProtocolException : " + e.getMessage()); }catch(IOException e){ Util.loge("IOException : " + e.getMessage()); } catch (Exception e) { Util.loge("Exception : " + e.getMessage()); } finally{ post.abort(); client = null; } return null; } }
基站定位的实现在CellLocationManager.java中
import java.io.BufferedReader; import java.io.InputStreamReader; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; 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 com.demo.location.Util; import android.content.Context; import android.telephony.TelephonyManager; import android.telephony.gsm.GsmCellLocation; public class CellLocationManager { private Context mContext; public CellLocationManager(Context context){ mContext = context; } /** 基站信息结构体 */ public class SCell{ public int MCC; public int MNC; public int LAC; public int CID; } /** * 获取基站信息 * * @throws Exception */ private SCell getCellInfo() throws Exception { SCell cell = new SCell(); /** 调用API获取基站信息 */ TelephonyManager mTelNet = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); GsmCellLocation location = (GsmCellLocation) mTelNet.getCellLocation(); if (location == null) throw new Exception("获取基站信息失败"); String operator = mTelNet.getNetworkOperator(); int mcc = Integer.parseInt(operator.substring(0, 3)); int mnc = Integer.parseInt(operator.substring(3)); int cid = location.getCid(); int lac = location.getLac(); /** 将获得的数据放到结构体中 */ cell.MCC = mcc; cell.MNC = mnc; cell.LAC = lac; cell.CID = cid; return cell; } public String getLocationCell(){ SCell cell = null; try { cell = getCellInfo(); } catch (Exception e1) { Util.loge("getLocationCell: getCellInfo: error: " + e1.getMessage()); return null; } /** 采用Android默认的HttpClient */ HttpClient client = new DefaultHttpClient(); /** 采用POST方法 */ HttpPost post = new HttpPost(Util.LOCATION_URL); try { /** 构造POST的JSON数据 */ JSONObject holder = new JSONObject(); holder.put("version", "1.1.0"); holder.put("host", Util.LOCATION_HOST); holder.put("address_language", "zh_CN"); holder.put("request_address", true); holder.put("radio_type", "gsm"); holder.put("carrier", "HTC"); JSONObject tower = new JSONObject(); tower.put("mobile_country_code", cell.MCC); // Util.logi("getLocationCell: mobile_country_code = " + cell.MCC ); tower.put("mobile_network_code", cell.MNC); // Util.logi("getLocationCell: mobile_network_code = " + cell.MNC ); tower.put("cell_id", cell.CID); // Util.logi("getLocationCell: cell_id = " + cell.CID ); tower.put("location_area_code", cell.LAC); // Util.logi("getLocationCell: location_area_code = " + cell.LAC ); JSONArray towerarray = new JSONArray(); towerarray.put(tower); holder.put("cell_towers", towerarray); StringEntity query = new StringEntity(holder.toString()); Util.logi("getLocationCell: holder: " + holder.toString()); post.setEntity(query); /** 发出POST数据并获取返回数据 */ HttpResponse response = client.execute(post); HttpEntity entity = response.getEntity(); BufferedReader buffReader = new BufferedReader(new InputStreamReader(entity.getContent())); StringBuffer strBuff = new StringBuffer(); String result = null; while ((result = buffReader.readLine()) != null) { strBuff.append(result); } /** 解析返回的JSON数据获得经纬度 */ JSONObject json = new JSONObject(strBuff.toString()); JSONObject subjosn = new JSONObject(json.getString("location")); String latitude = subjosn.getString("latitude"); String longitude = subjosn.getString("longitude"); return Util.getLocation(latitude, longitude); } catch (Exception e) { Util.loge("getLocationCell: error: " + e.getMessage()); } finally{ post.abort(); client = null; } return null; } }