android中获取位置的三种方式

1.GPS定位

2.基站定位

   此类位置的获取有赖于手机无线通讯信号,当手机处在信号覆盖范围内,手机可以获得该区域(即通讯术语中的“小区”)的识别号。因为这些识别号是惟一的,因此可以将识别号和地理坐标对应起来,因此根据识别号就可以知道地理位置。但是误差比较大。

   MCC(Mobile Country Code)、MNC(Mobile Network Code)、LAC(Location Aera Code)、CID(Cell Tower ID)是通讯业内的名词。MCC标识国家,MNC标识网络,两者组合起来则唯一标识一家通讯运营商。从维基百科上了解到,一个国家的MCC不唯一,例如中国有460和461,一家运营商也不只一个MNC,例如中国移动有00、02、07。LAC标识区域,类似于行政区域,运营商将大区域划分成若干小区域,每个区域分配一个LAC。CID标识基站,若手机处在工作状态,则必须要和一个通讯基站进行通讯,通过CID就可以确定手机所在的地理范围。

   在Android当中,大部分和通讯网络相关的信息都需要经过一项系统服务,即TelephoneManager来获得。

TelephonyManager mTelMan = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String operator = mTelMan.getNetworkOperator();
String mcc = operator.substring(0, 3);
String mnc = operator.substring(3);
GsmCellLocation location = (GsmCellLocation) mTelMan.getCellLocation();
int cid = location.getCid();
int lac = location.getLac();
通过上面的方法,可获得MCC、MNC、CID、LAC,对照Geolocation API Network Protocol,剩下不多的参数也可以获得,发起请求后根据响应内容即可得到地理位置信息。

请求(Request)的信息如下:

{"cell_towers":[{"mobile_network_code":"00","location_area_code":9733,
"mobile_country_code":"460","cell_id":17267},{"mobile_network_code":"00","location_area_code":9733,
"mobile_country_code":"460","cell_id":27852},{"mobile_network_code":"00","location_area_code":9733,
"mobile_country_code":"460","cell_id":27215},{"mobile_network_code":"00","location_area_code":9733,
"mobile_country_code":"460","cell_id":27198},{"mobile_network_code":"00","location_area_code":9484,
"mobile_country_code":"460","cell_id":27869},{"mobile_network_code":"00","location_area_code":9508,
"mobile_country_code":"460","cell_id":37297},{"mobile_network_code":"00","location_area_code":9733,
"mobile_country_code":"460","cell_id":27888}],
"host":"maps.google.com",
"version":"1.1.0"}
响应(Response)的信息如下:

{"location":{"latitude":23.12488,"longitude":113.271907,"accuracy":630.0},"access_token":"2:61tEAW-rONCT1_W-:JVpp2_jq5a0L-5JK"}
 
3.WIFI定位

  其原理是首先收集每个WIFI无线接入点的位置,对每个无线路由器进行唯一的标识,在数据库中注明这些接入点的具体位置。 使用时,一旦发现有WI-FI接入点,则进入到数据中查看匹配的记录,进而得到位置信息。

  WIFI定位主要取决于节点(node)的物理地址(mac address)。与提供TelephoneManager一样,Android也提供了获取WIFI信息的接口:WifiManager。

WifiManager wifiMan = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifiMan.getConnectionInfo();
String mac = info.getMacAddress();
String ssid = info.getSSID();
通过上面的方法,即可获得必要的请求参数。

发出的请求(Request)信息如下:

{"wifi_towers":[{"mac_address":"00:23:76:AC:41:5D","ssid":"Aspire-NETGEAR"}],"host":"maps.google.com","version":"1.1.0"}

响应(Response)的信息如下:

{"location":{"latitude":23.129075,"longitude":113.264423,"accuracy":140000.0},"access_token":"2:WRr36ynOz_d9mbw5:pRErDAmJXI8l76MU"}

 

---------以上简单介绍了android中获取位置的三种定位方式。实际开发中可利用android.location中的LocationManager类,该类封装了地理位置信息的接口,提供了GPS_PROVIDER和 NETWORK_PROVIDER。

如果开发的应用需要高精确性,那么可使用GPS_PROVIDER,但这也意味着应用无法在室内使用,待机时间缩短,响应时间稍长等问题;

如果开发的应用需要快速反应,对精度要求不怎么高,并且要尽可能节省电量,那么使用NETWORK_PROVIDER是不错的选择。

这里提一下,还有一个 PASSIVE_PROVIDER,在实际应用中较少使用。

1.如下代码就是设置从Network中获取位置:

LocationManager mLocMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

mLocMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0, mLocLis);

需要对应的权限:android.permission.ACCESS_COARSE_LOCATION

2.如下代码就是设置从GPS获取位置:

LocationManager mLocMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

mLocMan.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0, mLocLis);

需要对应的权限:android.permission.ACCESS_FINE_LOCATION

如果代码里使用了两个 PROVIDER,则只需要一个权限即可:android.permission.ACCESS_FINE_LOCATION。

以下是整个过程的代码:

public class DemoActivity extends Activity {
 
    private static final String TAG = "DemoActivity";
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
 
    public void onRequestLocation(View view) {
        switch (view.getId()){
        case R.id.gpsBtn:
            Log.d(TAG, "GPS button is clicked");
            requestGPSLocation();
            break;
        case R.id.telBtn:
            Log.d(TAG, "CellID button is clicked");
            requestTelLocation();
            break;
        case R.id.wifiBtn:
            Log.d(TAG, "WI-FI button is clicked");
            requestWIFILocation();
            break;
        case R.id.netBtn:
            Log.d(TAG, "Network button is clicked");
            requestNetworkLocation();
            break;
        }
    }
 
    private void requestTelLocation() {
        TelephonyManager mTelMan = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        // MCC+MNC. Unreliable on CDMA networks
        String operator = mTelMan.getNetworkOperator();
        String mcc = operator.substring(0, 3);
        String mnc = operator.substring(3);
 
        GsmCellLocation location = (GsmCellLocation) mTelMan.getCellLocation();
        int cid = location.getCid();
        int lac = location.getLac();
 
        JSONObject tower = new JSONObject();
        try {
            tower.put("cell_id", cid);
            tower.put("location_area_code", lac);
            tower.put("mobile_country_code", mcc);
            tower.put("mobile_network_code", mnc);
        } catch (JSONException e) {
            Log.e(TAG, "call JSONObject's put failed", e);
        }
 
        JSONArray array = new JSONArray();
        array.put(tower);
 
        List<NeighboringCellInfo> list = mTelMan.getNeighboringCellInfo();
        Iterator<NeighboringCellInfo> iter = list.iterator();
        NeighboringCellInfo cellInfo;
        JSONObject tempTower;
        while (iter.hasNext()) {
            cellInfo = iter.next();
            tempTower = new JSONObject();
            try {
                tempTower.put("cell_id", cellInfo.getCid());
                tempTower.put("location_area_code", cellInfo.getLac());
                tempTower.put("mobile_country_code", mcc);
                tempTower.put("mobile_network_code", mnc);
            } catch (JSONException e) {
                Log.e(TAG, "call JSONObject's put failed", e);
            }
            array.put(tempTower);
        }
 
        JSONObject object = createJSONObject("cell_towers", array);
        requestLocation(object);
    }
 
    private void requestWIFILocation() {
        WifiManager wifiMan = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        WifiInfo info = wifiMan.getConnectionInfo();
        String mac = info.getMacAddress();
        String ssid = info.getSSID();
 
        JSONObject wifi = new JSONObject();
        try {
            wifi.put("mac_address", mac);
            wifi.put("ssid", ssid);
        } catch (JSONException e) {
            e.printStackTrace();
        }
 
        JSONArray array = new JSONArray();
        array.put(wifi);
 
        JSONObject object = createJSONObject("wifi_towers", array);
        requestLocation(object);
    }
 
    private void requestLocation(JSONObject object) {
        Log.d(TAG, "requestLocation: " + object.toString());
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost("http://www.google.com/loc/json");
        try {
            StringEntity entity = new StringEntity(object.toString());
            post.setEntity(entity);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
 
        try {
            HttpResponse resp = client.execute(post);
            HttpEntity entity = resp.getEntity();
            BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
            StringBuffer buffer = new StringBuffer();
            String result = br.readLine();
            while (result != null) {
                buffer.append(result);
                result = br.readLine();
            }
 
            Log.d(TAG, buffer.toString());
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    private JSONObject createJSONObject(String arrayName, JSONArray array) {
        JSONObject object = new JSONObject();
        try {
            object.put("version", "1.1.0");
            object.put("host", "maps.google.com");
            object.put(arrayName, array);
        } catch (JSONException e) {
            Log.e(TAG, "call JSONObject's put failed", e);
        }
        return object;
    }
 
    private void requestGPSLocation() {
        LocationManager mLocMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        mLocMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 60, 100, mLocLis);
    }
 
    private void requestNetworkLocation() {
        LocationManager mLocMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        mLocMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60, 100, mLocLis);
    }
 
    private LocationListener mLocLis = new LocationListener() {
 
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            Log.d(TAG, "onStatusChanged, provider = " + provider);
        }
 
        @Override
        public void onProviderEnabled(String provider) {
            Log.d(TAG, "onProviderEnabled, provider = " + provider);
        }
 
        @Override
        public void onProviderDisabled(String provider) {
            Log.d(TAG, "onProviderDisabled, provider = " + provider);
        }
 
        @Override
        public void onLocationChanged(Location location) {
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            Log.d(TAG, "latitude: " + latitude + ", longitude: " + longitude);
        }
    };
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值