在android开发中地图和定位是很多软件不可或缺的内容,这些特色功能也给人们带来了很多方便。定位一般分为三种发方案:即GPS定位、Google网络定位以及基站定位

最简单的手机定位方式当然是通过GPS模块(现在大部分的智能机应该都有了)。GPS方式准确度是最高的,但是它的缺点也非常明显:1,比较耗电;2,绝大部分用户默认不开启GPS模块;3,从GPS模块启动到获取第一次定位数据,可能需要比较长的时间;4,室内几乎无法使用。这其中,缺点2,3都是比较致命的。需要指出的是,GPS走的是卫星通信的通道,在没有网络连接的情况下也能用。
另外一种常见的定位方式是基站定位。大致思路就是采集到手机上的基站ID号(cellid)和其它的一些信息(MNC,MCC,LAC等等),然后通过网络访问一些定位服务,获取并返回对应的经纬度坐标。基站定位的精确度不如GPS,但好处是能够在室内用,只要网络通畅就行。
还有Wifi定位。和基站定位类似,这种方式是通过获取当前所用的wifi的一些信息,然后访问网络上的定位服务以获得经纬度坐标。因为它和基站定位其实都需要使用网络,所以在Android也统称为Network方式。
最后需要解释一点的是AGPS方式。很多人将它和基站定位混为一谈,但其实AGPS的本质仍然是GPS,只是它会使用基站信息对获取GPS进行辅助,然后还能对获取到的GPS结果进行修正,所以AGPS要比传统的GPS更快,准确度略高。

本文分别介绍GPS定位、以及基于Google的网络Wifi定位,以及最后的使用百度LBS的定位(百度LBS的定位功能比较强大,集成了GPS,网络wifi以及基站定位三种定位方法)。主要用例就是利用这三种方法获取位置经纬度,以及利用经纬度来获取所在的城市及区域

而根据经纬度来获取所在位置的城市及区域全部都是采用百度地图的API:http://api.map.baidu.com/geocoder?output=json&location=39.983228,116.491146key=您的key

,这个key需要你自己申请百度开发者账号来得到的。

首先来看看定位实例效果图如下:

1.GPS定位

(1)打开GPS设置

  1. private void openGPSSettings() {
  2. LocationManager alm = (LocationManager) this
  3. .getSystemService(Context.LOCATION_SERVICE);
  4. if (alm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
  5. Toast.makeText(this, "GPS模块正常", Toast.LENGTH_SHORT).show();
  6. doWork();
  7. return;
  8. } else {
  9. Toast.makeText(this, "请开启GPS!", Toast.LENGTH_SHORT).show();
  10. Intent intent = new Intent(Settings.ACTION_SECURITY_SETTINGS);
  11. startActivityForResult(intent, 0); // 此为设置完成后返回到获取界面
  12. }
  13.  
  14. }

(2)通过GPS获取经纬度信息

  1. private void doWork() {
  2.  
  3. String msg = "";
  4.  
  5. LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
  6.  
  7. Criteria criteria = new Criteria();
  8. // 获得最好的定位效果
  9. criteria.setAccuracy(Criteria.ACCURACY_FINE);
  10. criteria.setAltitudeRequired(false);
  11. criteria.setBearingRequired(false);
  12. criteria.setCostAllowed(false);
  13. // 使用省电模式
  14. criteria.setPowerRequirement(Criteria.POWER_LOW);
  15. // 获得当前的位置提供者
  16. String provider = locationManager.getBestProvider(criteria, true);
  17. // 获得当前的位置
  18. Location location = locationManager.getLastKnownLocation(provider);
  19.  
  20. double latitude = location.getLatitude();
  21. double longitude = location.getLongitude();
  22.  
  23. locationString = "&location=" + latitude + "," + longitude;
  24. keyString = "&key=您的key";
  25. questURL = questURL + locationString + keyString;
  26.  
  27. new ReadJSONFeedTask().execute(questURL);
  28. }

(3)由经纬度获取所在城市和区域的ReadJSONFeedTask类的实现:

  1. /**
  2. * 由经纬度获取所在的城市及区域信息
  3. * @author caizhiming
  4. *
  5. */
  6. private class ReadJSONFeedTask extends AsyncTask<String, Void, String> {
  7.  
  8. StringBuilder stringBuilder = new StringBuilder();
  9.  
  10. @Override
  11. protected String doInBackground(String... urls) {
  12. // TODO Auto-generated method stub
  13. return readJSONFeed(urls[0]);
  14. }
  15.  
  16. @Override
  17. protected void onPostExecute(String result) {
  18. // TODO Auto-generated method stub
  19. String strItem;
  20.  
  21. try {
  22.  
  23. JSONObject jsonObject = new JSONObject(result);
  24. JSONObject resultObject = jsonObject.getJSONObject("result");
  25. JSONObject addressComponentObject = resultObject
  26. .getJSONObject("addressComponent");
  27. String city = addressComponentObject.getString("city");
  28. String district = addressComponentObject.getString("district");
  29.  
  30. city = "城市:" + city;
  31. district = " 区:" + district;
  32. stringBuilder.append(city + district);
  33. textView.setText(stringBuilder.toString());
  34. } catch (JSONException e) {
  35. // TODO Auto-generated catch block
  36. e.printStackTrace();
  37. }
  38.  
  39. }
  40.  
  41. }
  42. /**
  43. * 请求json数据
  44. * @param url
  45. * @author caizhiming
  46. */
  47. public String readJSONFeed(String url) {
  48. StringBuilder stringBuilder = new StringBuilder();
  49. HttpClient client = new DefaultHttpClient();
  50. HttpGet httpGet = new HttpGet(url);
  51. HttpResponse response;
  52. try {
  53. response = client.execute(httpGet);
  54. StatusLine statusLine = response.getStatusLine();
  55. int statusCode = statusLine.getStatusCode();
  56. if (statusCode == 200) {
  57. HttpEntity entity = response.getEntity();
  58. InputStream content = entity.getContent();
  59. BufferedReader reader = new BufferedReader(
  60. new InputStreamReader(content));
  61. String line;
  62. while ((line = reader.readLine()) != null) {
  63. stringBuilder.append(line);
  64. }
  65. } else {
  66. Log.e("JSON", "Failed to download file");
  67. }
  68. } catch (ClientProtocolException e) {
  69. // TODO Auto-generated catch block
  70. e.printStackTrace();
  71. } catch (IOException e) {
  72. // TODO Auto-generated catch block
  73. e.printStackTrace();
  74. }
  75. return stringBuilder.toString();
  76. }

2. 网络WIFI定位

(1) 通过网络WIFI来获取经纬度信息:

  1. /* ====================Google Location By NetWork=========================== */
  2. private void getLocationByNetwork() {
  3. LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
  4. LocationListener locationListener = new LocationListener() {
  5.  
  6. // Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
  7. @Override
  8. public void onStatusChanged(String provider, int status,
  9. Bundle extras) {
  10.  
  11. }
  12.  
  13. // Provider被enable时触发此函数,比如GPS被打开
  14. @Override
  15. public void onProviderEnabled(String provider) {
  16.  
  17. }
  18.  
  19. // Provider被disable时触发此函数,比如GPS被关闭
  20. @Override
  21. public void onProviderDisabled(String provider) {
  22.  
  23. }
  24.  
  25. // 当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
  26. @Override
  27. public void onLocationChanged(Location location) {
  28. if (location != null) {
  29. Log.e("Map",
  30. "Location changed : Lat: " + location.getLatitude()
  31. + " Lng: " + location.getLongitude());
  32. }
  33. }
  34. };
  35. locationManager.requestLocationUpdates(
  36. LocationManager.NETWORK_PROVIDER, 1000, 0, locationListener);
  37. Location location = locationManager
  38. .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
  39. double latitude = 0;
  40. double longitude = 0;
  41. if (location != null) {
  42. latitude = location.getLatitude(); // 经度
  43. longitude = location.getLongitude(); // 纬度
  44. }
  45.  
  46. locationString = "&location=" + latitude + "," + longitude;
  47. keyString = "&key=你的key";
  48. questURL = questURL + locationString + keyString;
  49. Toast.makeText(this, locationString, Toast.LENGTH_LONG).show();
  50. new ReadJSONFeedTask().execute(questURL);
  51. }

(2)由经纬度获取所在城市和区域的ReadJSONFeedTask类的实现:

  1. /**
  2. * 由经纬度获取所在的城市及区域信息
  3. * @author caizhiming
  4. *
  5. */
  6. private class ReadJSONFeedTask extends AsyncTask<String, Void, String> {
  7.  
  8. StringBuilder stringBuilder = new StringBuilder();
  9.  
  10. @Override
  11. protected String doInBackground(String... urls) {
  12. // TODO Auto-generated method stub
  13. return readJSONFeed(urls[0]);
  14. }
  15.  
  16. @Override
  17. protected void onPostExecute(String result) {
  18. // TODO Auto-generated method stub
  19. String strItem;
  20.  
  21. try {
  22.  
  23. JSONObject jsonObject = new JSONObject(result);
  24. JSONObject resultObject = jsonObject.getJSONObject("result");
  25. JSONObject addressComponentObject = resultObject
  26. .getJSONObject("addressComponent");
  27. String city = addressComponentObject.getString("city");
  28. String district = addressComponentObject.getString("district");
  29.  
  30. city = "城市:" + city;
  31. district = " 区:" + district;
  32. stringBuilder.append(city + district);
  33. textView.setText(stringBuilder.toString());
  34. } catch (JSONException e) {
  35. // TODO Auto-generated catch block
  36. e.printStackTrace();
  37. }
  38.  
  39. }
  40.  
  41. }
  42. /**
  43. * 请求json数据
  44. * @param url
  45. * @author caizhiming
  46. */
  47. public String readJSONFeed(String url) {
  48. StringBuilder stringBuilder = new StringBuilder();
  49. HttpClient client = new DefaultHttpClient();
  50. HttpGet httpGet = new HttpGet(url);
  51. HttpResponse response;
  52. try {
  53. response = client.execute(httpGet);
  54. StatusLine statusLine = response.getStatusLine();
  55. int statusCode = statusLine.getStatusCode();
  56. if (statusCode == 200) {
  57. HttpEntity entity = response.getEntity();
  58. InputStream content = entity.getContent();
  59. BufferedReader reader = new BufferedReader(
  60. new InputStreamReader(content));
  61. String line;
  62. while ((line = reader.readLine()) != null) {
  63. stringBuilder.append(line);
  64. }
  65. } else {
  66. Log.e("JSON", "Failed to download file");
  67. }
  68. } catch (ClientProtocolException e) {
  69. // TODO Auto-generated catch block
  70. e.printStackTrace();
  71. } catch (IOException e) {
  72. // TODO Auto-generated catch block
  73. e.printStackTrace();
  74. }
  75. return stringBuilder.toString();
  76. }

3.使用百度LBS的SDK定位

(1)导入百度的LBS的SDK开发Jar包,开发者可以到百度开发者中心去下载即可。即BaiduLBS_Android.jar包,放在项目的libs目录下即可。需要注意的是,同时需要在libs目录下建立armeabi目录,并在该目录下放sdk中的liblocSDK4d.so文件,这样才能使用sdk。

(2)初始化百度LBS定位信息,包括初始化定位客户端,定位监听器,定位模式等信息:

  1. /**
  2. * baidu lbs location
  3. *
  4. * @author caizhiming
  5. */
  6. private void InitLocation() {
  7. Log.v("LocationActivity", "InitLocation");
  8.  
  9. mLocationClient = new LocationClient(this.getApplicationContext()); // 声明LocationClient类
  10. myListener = new MyLocationListener();
  11. mLocationClient.registerLocationListener(myListener); // 注册监听函数
  12.  
  13. LocationClientOption option = new LocationClientOption();
  14. option.setLocationMode(tempMode);// 设置定位模式
  15. option.setCoorType(tempcoor);// 返回的定位结果是百度经纬度,默认值gcj02
  16. int span = 3000;
  17.  
  18. option.setScanSpan(span);// 设置发起定位请求的间隔时间为5000ms
  19. option.setIsNeedAddress(false);
  20. mLocationClient.setLocOption(option);
  21. }

另外,还需要在AndroidMenifest.xml中配置key信息如下:

  1. <!-- meta-data需要写在application中 -->
  2. <meta-data
  3. android:name="com.baidu.lbsapi.API_KEY"
  4. android:value="您的key" />

最后还需要AndroidMenifest.xml中配置相应需要的权限如下:

  1. <!-- baidu lbs -->
  2. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
  3. </uses-permission>
  4. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >
  5. </uses-permission>
  6. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
  7. </uses-permission>
  8. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
  9. </uses-permission>
  10. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
  11. </uses-permission>
  12. <uses-permission android:name="android.permission.READ_PHONE_STATE" >
  13. </uses-permission>
  14. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
  15. </uses-permission>
  16. <uses-permission android:name="android.permission.INTERNET" />
  17. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >
  18. </uses-permission>
  19. <uses-permission android:name="android.permission.READ_LOGS" >
  20. </uses-permission>
  21. <uses-permission android:name="android.permission.VIBRATE" />
  22. <uses-permission android:name="android.permission.WAKE_LOCK" />
  23. <uses-permission android:name="android.permission.WRITE_SETTINGS" />

(3)启动百度LBS的定位服务并获取经纬度等信息:

  1. /**
  2. * baidu lbs location
  3. *
  4. * @author caizhiming
  5. */
  6. private void getLocationByBaiduLBS() {
  7.  
  8. Log.v("LocationActivity", "getLocationByBaiduLBS");
  9. mLocationClient.start();
  10. }
  11. /**
  12. * baidu lbs location
  13. *
  14. * @author caizhiming
  15. */
  16. public class MyLocationListener implements BDLocationListener {
  17. @Override
  18. public void onReceiveLocation(BDLocation location) {
  19. Log.v("LocationActivity", "MyLocationListener-onReceiveLocation");
  20. if (location == null)
  21. return;
  22. StringBuffer sb = new StringBuffer(256);
  23. sb.append("time : ");
  24. sb.append(location.getTime());
  25. sb.append("\nerror code : ");
  26. sb.append(location.getLocType());
  27. sb.append("\nlatitude : ");
  28. sb.append(location.getLatitude());
  29. sb.append("\nlontitude : ");
  30. sb.append(location.getLongitude());
  31. sb.append("\nradius : ");
  32. sb.append(location.getRadius());
  33. if (location.getLocType() == BDLocation.TypeGpsLocation) {
  34. sb.append("\nspeed : ");
  35. sb.append(location.getSpeed());
  36. sb.append("\nsatellite : ");
  37. sb.append(location.getSatelliteNumber());
  38. } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
  39. sb.append("\naddr : ");
  40. sb.append(location.getAddrStr());
  41. }
  42. logMsg(sb.toString());
  43.  
  44. locationString = "&location=" + location.getLatitude() + ","
  45. + location.getLongitude();
  46. keyString = "&key=你的key";
  47. questURL = questURL + locationString + keyString;
  48. new ReadJSONFeedTask().execute(questURL);
  49.  
  50. }
  51. }

(4)由经纬度获取所在城市和区域的ReadJSONFeedTask类的实现:

  1. /**
  2. * 由经纬度获取所在的城市及区域信息
  3. * @author caizhiming
  4. *
  5. */
  6. private class ReadJSONFeedTask extends AsyncTask<String, Void, String> {
  7.  
  8. StringBuilder stringBuilder = new StringBuilder();
  9.  
  10. @Override
  11. protected String doInBackground(String... urls) {
  12. // TODO Auto-generated method stub
  13. return readJSONFeed(urls[0]);
  14. }
  15.  
  16. @Override
  17. protected void onPostExecute(String result) {
  18. // TODO Auto-generated method stub
  19. String strItem;
  20.  
  21. try {
  22.  
  23. JSONObject jsonObject = new JSONObject(result);
  24. JSONObject resultObject = jsonObject.getJSONObject("result");
  25. JSONObject addressComponentObject = resultObject
  26. .getJSONObject("addressComponent");
  27. String city = addressComponentObject.getString("city");
  28. String district = addressComponentObject.getString("district");
  29.  
  30. city = "城市:" + city;
  31. district = " 区:" + district;
  32. stringBuilder.append(city + district);
  33. textView.setText(stringBuilder.toString());
  34. } catch (JSONException e) {
  35. // TODO Auto-generated catch block
  36. e.printStackTrace();
  37. }
  38.  
  39. }
  40.  
  41. }
  42. /**
  43. * 请求json数据
  44. * @param url
  45. * @author caizhiming
  46. */
  47. public String readJSONFeed(String url) {
  48. StringBuilder stringBuilder = new StringBuilder();
  49. HttpClient client = new DefaultHttpClient();
  50. HttpGet httpGet = new HttpGet(url);
  51. HttpResponse response;
  52. try {
  53. response = client.execute(httpGet);
  54. StatusLine statusLine = response.getStatusLine();
  55. int statusCode = statusLine.getStatusCode();
  56. if (statusCode == 200) {
  57. HttpEntity entity = response.getEntity();
  58. InputStream content = entity.getContent();
  59. BufferedReader reader = new BufferedReader(
  60. new InputStreamReader(content));
  61. String line;
  62. while ((line = reader.readLine()) != null) {
  63. stringBuilder.append(line);
  64. }
  65. } else {
  66. Log.e("JSON", "Failed to download file");
  67. }
  68. } catch (ClientProtocolException e) {
  69. // TODO Auto-generated catch block
  70. e.printStackTrace();
  71. } catch (IOException e) {
  72. // TODO Auto-generated catch block
  73. e.printStackTrace();
  74. }
  75. return stringBuilder.toString();
  76. }

Android开发之位置定位详解与实例解析(GPS定位、Google网络定位,BaiduLBS(SDK)定位)的更多相关文章

  1. Android开发——事件分发机制详解

    0. 前言   转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52566965 深入学习事件分发机制,是为了解决在Android开发中 ...

  2. Android开发 ExpandableListView 可折叠列表详解

    前言 在需要实现一个List的item需要包含列表的时候,我们就可以选择ExpandableListView. 其实这个View的原始设计还是ListView的那套.就是增加2层的ListView而已 ...

  3. Android开发:程序目录结构详解

    HelloWorld程序的目录结构概述 我们可以在文件夹中看到,HelloWorld程序的目录主要包括:src文件夹.gen文件夹.Android文件夹.assets.res文件夹. AndroidM ...

  4. Android 开发 存储目录的详解

    简介 Android设备,有3个地方的文件存储位置,他们分别是: 内部存储空间(用户无法浏览到此目录) 外部存储空间(就是手机自身的文件管理目录,用户可以浏览) SD卡的存储空间(需要插入T卡) Sh ...

  5. Android 开发 MaterialDialog框架的详解

    前言 开始之前还是需要废话一下,因为有一些坑需要告知.首先MaterialDialog在GitHub上作者已经转型使用100% Kotlin语言编写,虽然可以在Java里调用Kotlin使用.但是个人 ...

  6. android 开发 View _5_ Paint详解

    转载:http://blog.csdn.net/abcdef314159 //Paint的setStyle,Style共有3种 setStyle(Style style) Paint.Style.FI ...

  7. android开发之动画的详解 整理资料 Android开发程序小冰整理

    /** * 作者:David Zheng on 2015/11/7 15:38 * *  网站:http://www.93sec.cc * *  微博:http://weibo.com/mcxiaob ...

  8. Android开发之线性布局详解(布局权重)

    布局权重 线性布局支持给个别的子视图设定权重,通过android:layout_weight属性.就一个视图在屏幕上占多大的空间而言,这个属性给其设 定了一个重要的值.一个大的权重值,允许它扩大到填充 ...

  9. Android开发——HandlerThread以及IntentService详解

    .HandlerThread Android API提供了HandlerThread来创建线程.官网的解释是: //Handy class for starting a new thread that ...

随机推荐

  1. SSH框架中配置Hibernate使用proxool连接池

    一.导入proxool.jar包 案例用的是proxool-0.8.3.jar,一般通过MyEclipse配置的SSH都会包含这个jar,如果没有,就去网上搜下下载导入就好了. 二.新建Proxool ...

  2. 【HDOJ】1253 胜利大逃亡

    经典的BFS,需要注意的是当前时间超过最小时间,输出-1.同时,队列为空时还未返回,证明并未找到终点(可能终点为墙).此时也应该输出-1,这个部分容易wa. #include <cstdio&g ...

  3. hdu4705Y

    链接 这题可以算树形DP吧 树上的递推 对于树上的某个节点 反着算比较好做 就是算有多少有simple路径的 固定某个节点u 另两个节点 有两种取法 1.从不同子树里各选一个 2.从所有子树里选一个 ...

  4. 普通pc电脑安装苹果系统mac_详细教程(精)附带所有工具下载

    苹果操作系统只允许在苹果电脑上面安装和使用.和Windows不一样,要在PC上安装,需要一系列的模拟和破解.破解安装的过程很繁琐而具有挑战性,以下是安装10A432雪豹的PC安装指南,附带25张图片帮 ...

  5. 安装Intel CPU的Android模拟器

    1. 用Android SDK Manager安装Extras/Intel x86 Emulator Accelarator(HAXM) 2. 用Android SDK Manager安装Androi ...

  6. 两种应该掌握的排序方法--------1.shell Sort

    先了解下什么都有什么排序算法 https://en.wikipedia.org/wiki/Sorting_algorithm http://zh.wikipedia.org/zh/%E6%8E%92% ...

  7. LittleTools之批量替换工具

    身为程序员,有很多事情都可以交给机器来做,这样可以提高工作效率. 在此先写个批量替换工具,用来将某些对象统一替换为另一对象. 比方说场景中摆了一堆树,位置.比例.旋转都已经调好了,但是对树的样式不太满 ...

  8. 2015年9月28日html基础了解学习

    数据库与C#都是在后台运行的逻辑,而html,css,js,jq是在网页前台显示的一些效果.后台要考虑到优化性能效率等等,而前台要吸引到客户,要有更好的客户体验. 通用化,还是效率更高,在做项目中是要 ...

  9. Clean Code – Chapter 6 Objects and Data Structures

    Data Abstraction Hiding implementation Data/Object Anti-Symmetry Objects hide their data behind abst ...

  10. linux shell 中"2>&1"含义

    脚本是:      nohup /mnt/Nand3/H2000G  >/dev/null  2>&1  &      对于& 1 更准确的说应该是文件描述符 1, ...