zoukankan      html  css  js  c++  java
  • Andriod定位实现(Google)

    基于位置的服务简称 LBS,主要的工作原理就是利用无线电通讯网络或 GPS 等定位方式来确定出移动设备所在的位置.
      定位过程如下:

    1.LocationManager的使用

      要想使用 LocationManager就必须要先获取到它的实例, 我们可以调用 Context
    的 getSystemService()方法获取到。getSystemService()方法接收一个字符串参数用于确定获取
    系统的哪个服务, 这里传入 Context.LOCATION_SERVICE 即可。 因此, 获取 LocationManager
    的实例就可以写成:
    LocationManager locationManager = (LocationManager)
    getSystemService(Context.LOCATION_SERVICE);
    接着我们需要选择一个位置提供器来确定设备当前的位置。Android 中一般有三种位置
    提供器可供选择,GPS_PROVIDER、NETWORK_PROVIDER 和 PASSIVE_PROVIDER。其
    中前两种使用的比较多,分别表示使用 GPS 定位和使用网络定位。这两种定位方式各有特
    点,GPS 定位的精准度比较高,但是非常耗电,而网络定位的精准度稍差,但耗电量比较少。
    我们应该根据自己的实际情况来选择使用哪一种位置提供器, 当位置精度要求非常高的时候,
    最好使用 GPS_PROVIDER,而一般情况下,使用 NETWORK_PROVIDER 会更加得划算。
    将选择好的位置提供器传入到 getLastKnownLocation()方法中, 就可以得到一个 Location
    对象,如下所示:
    String provider = LocationManager.NETWORK_PROVIDER;
    Location location = locationManager.getLastKnownLocation(provider);
    这个 Location 对象中包含了经度、纬度、海拔等一系列的位置信息,然后从中取出我们
    所关心的那部分数据即可。
    如果有些时候你想让定位的精度尽量高一些,但又不确定 GPS 定位的功能是否已经启
    用,这个时候就可以先判断一下有哪些位置提供器可用,如下所示:
    List<String> providerList = locationManager.getProviders(true);
    可以看到,getProviders()方法接收一个布尔型参数,传入 true 就表示只有启用的位置提
    供器才会被返回。之后再从 providerList 中判断是否包含 GPS 定位的功能就行了。
    LocationManager 还提供了一个 requestLocationUpdates()方法,
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10,
    new LocationListener() {
    @Override
    public void onStatusChanged(String provider, int status, Bundle
    extras) {
    }
    @Override
    public void onProviderEnabled(String provider) {
    }
    @Override
    public void onProviderDisabled(String provider) {
    }
    @Override
    public void onLocationChanged(Location location) {
    }
    });
    这里 requestLocationUpdates()方法接收四个参数,第一个参数是位置提供器的类型,第
    二个参数是监听位置变化的时间间隔,以毫秒为单位,第三个参数是监听位置变化的距离间
    隔,以米为单位,第四个参数则是 LocationListener监听器。这样的话,LocationManager每隔
    5 秒钟会检测一下位置的变化情况,当移动距离超过 10 米的时候,就会调用 LocationListener
    的 onLocationChanged()方法,并把新的位置信息作为参数传入。

    另外,获取设备当前的位置信息也是要声明权限的,因此还需要修改 AndroidManifest.xml
    中的代码,<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    反向地理编码,看得懂的位置信息
    Geocoding API 的用法
    GeocodingAPI 的工作原理并不神秘,其实就是利用HTTP 协议。
    在手机端我们可以向谷歌的服务器发起一条 HTTP 请求,并将经纬度的值作为参数一同传递
    过去,然后服务器会帮我们将这个经纬值转换成看得懂的位置信息,再将这些信息返回给手
    机端,最后手机端去解析服务器返回的信息,并进行处理就可以了。
    Geocoding API 中规定了很多接口,其中反向地理编码的接口如下:
    http://maps.googleapis.com/maps/api/geocode/json? latlng=40.714224,- 73.961452&sensor=true_or_false

    private void showLocation(final Location location) {
    new Thread(new Runnable() {
    @Override
    public void run() {
    try {
    // 组装反向地理编码的接口地址
    StringBuilder url = new StringBuilder();
    url.append("http://maps.googleapis.com/maps/api/geocode/json?latlng=");
    url.append(location.getLatitude()).append(",")
    url.append(location.getLongitude());
    url.append("&sensor=false");
    HttpClient httpClient = new DefaultHttpClient();
    HttpGet httpGet = new HttpGet(url.toString());
    // 在请求消息头中指定语言,保证服务器会返回中文数据
    httpGet.addHeader("Accept-Language", "zh-CN");
    HttpResponse httpResponse = httpClient.execute(httpGet);
    if (httpResponse.getStatusLine().getStatusCode() == 200) {
    HttpEntity entity = httpResponse.getEntity();
    String response = EntityUtils.toString(entity,
    "utf-8");
    JSONObject jsonObject = new JSONObject(response);
    // 获取results节点下的位置信息
    JSONArray resultArray = jsonObject.getJSONArray
    ("results");
    if (resultArray.length() > 0) {
    JSONObject subObject = resultArray.
    getJSONObject(0);
    // 取出格式化后的位置信息
    第一行代码——Android
    420
    String address = subObject.getString
    ("formatted_address");
    Message message = new Message();
    message.what = SHOW_LOCATION;
    message.obj = address;
    handler.sendMessage(message);
    }
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }).start();
    }
    private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
    switch (msg.what) {
    case SHOW_LOCATION:
    String currentPosition = (String) msg.obj;
    positionTextView.setText(currentPosition);
    break;
    default:
    break;
    }
    }
    };
    观察 showLocation()方法,由于我们要在这里发起网络请求,因此必须开启一个子线程。
    在子线程中首先是通过 StringBuilder 组装了一个反向地理编码接口地址的字符串,然后使用
    HttpClient 去请求这个地址就好了。注意在 HttpGet 中我们还添加了一个消息头,消息头中将
    语言类型指定为简体中文,不然服务器会默认返回英文的位置信息。

  • 相关阅读:
    Xilinx SelectIO资源的使用总结
    Altera usbblaster驱动无法安装的解决办法
    Xilinx FPGA的约束设计和时序分析总结
    OpenMANIPULATORX基本操作
    OpenMANIPULATORX ROS包安装 (Melodic)
    .xacro文件
    open_manipulator OpenCR代码解读
    OpenMANIPULATORX GUI
    ROS建模 urdf
    多机器人Gazebo仿真
  • 原文地址:https://www.cnblogs.com/new-comer/p/5371924.html
Copyright © 2011-2022 走看看