位置服务

起草人: 陈曾华 日期:15年11月30日

修改完善:徐荣涛 日期:15年11月30日

一、实验目的

学习一下基于位置的服务究竟是如何实现的,学会使用LocationManager找到自己的位置,能够使用反向地理编码对经纬度进行解析。

二、基础知识

简要介绍本次实验所需掌握的基础知识

  • 知识点1:

    熟悉LocationManager的基本用法,确定自己位置的经纬度。
    

    1.获取 LocationManager的实例可以写成: LocationManager locationManager = (LocationManager); getSystemService(Context.LOCATION_SERVICE); 使用LocationManager必须要先获取到它的实例, 可以调用Context的 getSystemService()方法获取到。 getSystemService()方法接收一个字符串参数用于确定获取系统的哪个服务, 这里传入 Context.LOCATION_SERVICE 即可。 2.接着需要选择一个位置提供器来确定设备当前的位置。Android中一般有三种位置提供器可供选择,GPS_PROVIDER、NETWORK_PROVIDER 和 PASSIVE_PROVIDER。其中前两种使用的比较多,分别表示使用GPS定位和使用网络定位。这两种定位方式各有特点,GPS定位的精准度比较高,但是非常耗电,而网络定位的精准度稍差,但耗电量比较少。 将选择好的位置提供器传入到 getLastKnownLocation()方法中, 就可以得到一个 Location对象,如下所示 String provider = LocationManager.NETWORK_PROVIDER; Location location = locationManager.getLastKnownLocation(provider); 这个 Location 对象中包含了经度、纬度、海拔等一系列的位置信息,然后从中取出需要的那部分数据即可。如果想让定位的精度尽量高一些,但又不确定GPS定位的功能是否已经启用,此时就可以先判断一下有哪些位置提供器可用,如下所示: List providerList = locationManager.getProviders(true); 3.LocationManager 提供了一个requestLocationUpdates()方法,只要传入一个LocationListener的实例,并简单配置几个参数就可以实现随时随地获取当前设备的位置信息,写法如下: 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()方法,并把新的位置信息作为参数传入。

  • 知识点3:

    知识点介绍
    

    三、实验内容及步骤

3.1 实验内容

*1.找到设备当前位置的经纬度

*2.使用反向地理编码,获得中文地理位置。

3.2 实验步骤

1.新建一个 LocationTest项目,修改 activity_main.xml 中的代码,如下所示:

2.然后修改 MainActivity 中的代码,如下所示: public class MainActivity extends Activity { private TextView positionTextView; private LocationManager locationManager; private String provider; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); positionTextView = (TextView) findViewById(R.id.position_text_view); locationManager = (LocationManager) getSystemService(Context. LOCATION_SERVICE); // 获取所有可用的位置提供器 List providerList = locationManager.getProviders(true); if (providerList.contains(LocationManager.GPS_PROVIDER)) { provider = LocationManager.GPS_PROVIDER; } else if (providerList.contains(LocationManager.NETWORK_PROVIDER)) { provider = LocationManager.NETWORK_PROVIDER; } else { // 当没有可用的位置提供器时,弹出Toast提示用户 Toast.makeText(this, "No location provider to use", Toast.LENGTH_SHORT).show(); return; } Location location = locationManager.getLastKnownLocation(provider); if (location != null) { // 显示当前设备的位置信息 showLocation(location); } locationManager.requestLocationUpdates(provider, 5000, 1, locationListener); } protected void onDestroy() { super.onDestroy(); if (locationManager != null) { // 关闭程序时将监听器移除 locationManager.removeUpdates(locationListener); } } LocationListener locationListener = 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) { // 更新当前设备的位置信息 showLocation(location); } }; private void showLocation(Location location) { String currentPosition = "latitude is " + location.getLatitude() + "\n"

  • "longitude is " + location.getLongitude(); positionTextView.setText(currentPosition); } }

3.获取设备当前的位置信息需要声明权限,因此修改AndroidManifest.xml中的代码,如下所示:

</manifest> 4.运行程序就可以看到手机当前位置的经纬度信息了,如下图所示:

5.为了获得一般用户能够看得懂的中文位置信息,修改 MainActivity 中的代码,如下所示: public class MainActivity extends Activity { public static final int SHOW_LOCATION = 0; …… 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); // 取出格式化后的位置信息 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; } } }; }

6.由于在这里使用到了网络功能,因此还需要在 AndroidManifest.xml 中添加权限声明,如下所示:

</manifest> 7.运行程序结果如下,就可以获得一般用户能够看得懂的中文位置信息,效果如下:

四、常见问题及注意事项

详细描述本此实验的可能会遇到的问题以及相关的注意事项

results matching ""

    No results matching ""