Android定位功能

简介:

废话不多说,直接开始说说与实现Android定位有关的API吧。

  这些API都在android.location包下,一共有三个接口和八个类。它们配合使用即可实现定位功能。

 

  三个接口:

  GpsStatus.Listener: 这是一个当GPS状态发生改变时,用来接收通知的接口。

  GpsStatus.NmeaListener: 这是一个用来从GPS里接收Nmea-0183(为海用电子设备制定的标准格式)信息的接口。

  LocationListener: 位置监听器,用于接收当位置信息发生改变时从LocationManager接收通知的接口。

 

  八个类:

  Address: 描述地址的类,比如:北京天安门

  Criteria: 用于描述Location Provider标准的类,标准包括位置精度水平,电量消耗水平,是否获取海拔、方位信息,是否允许接收付费服务。

  GeoCoder: 用于处理地理位置的编码。

  GpsSatellite: 和GpsStatus联合使用,用于描述当前GPS卫星的状态。

  GpsStatus: 和GpsStatus.Listener联合使用,用于描述当前GPS卫星的状态。

  Location: 用于描述位置信息。

  LocationManager: 通过此类获取和调用系统位置服务

  LocationProvider: 用于描述Location Provider的抽象超类,一个LocationProvider应该能够周期性的报告当前设备的位置信息。

 

  这里通过一个代码示例,演示一下如何实现定位。

  首先,在AndroidManifest.xml清单文件里需要加入ACCESS_FINE_LOCATION权限

1 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
其次,实现代码如下:
001 package com.test;
002   
003  import java.io.IOException;
004  import java.util.List;
005   
006  import android.app.Activity;
007  import android.location.Address;
008  import android.location.Criteria;
009  import android.location.Geocoder;
010  import android.location.Location;
011  import android.location.LocationListener;
012  import android.location.LocationManager;
013  import android.os.Bundle;
014  import android.util.Log;
015  import android.widget.Toast;
016   
017  public class MainActivity extends Activity {
018      @Override
019      public void onCreate(Bundle savedInstanceState) {
020         super.onCreate(savedInstanceState);
021         setContentView(R.layout.main);
022          
023         //获取到LocationManager对象
024         LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
025         //创建一个Criteria对象
026         Criteria criteria = new Criteria();
027         //设置粗略精确度
028         criteria.setAccuracy(Criteria.ACCURACY_COARSE);
029         //设置是否需要返回海拔信息
030         criteria.setAltitudeRequired(false);
031         //设置是否需要返回方位信息
032         criteria.setBearingRequired(false);
033         //设置是否允许付费服务
034         criteria.setCostAllowed(true);
035         //设置电量消耗等级
036         criteria.setPowerRequirement(Criteria.POWER_HIGH);
037         //设置是否需要返回速度信息
038         criteria.setSpeedRequired(false);
039   
040         //根据设置的Criteria对象,获取最符合此标准的provider对象
041         String currentProvider = locationManager.getBestProvider(criteria, true);
042         Log.d("Location""currentProvider: " + currentProvider);
043         //根据当前provider对象获取最后一次位置信息
044         Location currentLocation = locationManager.getLastKnownLocation(currentProvider);
045         //如果位置信息为null,则请求更新位置信息
046         if(currentLocation == null){
047             locationManager.requestLocationUpdates(currentProvider, 00, locationListener);
048         }
049         //直到获得最后一次位置信息为止,如果未获得最后一次位置信息,则显示默认经纬度
050         //每隔10秒获取一次位置信息
051         while(true){
052             currentLocation = locationManager.getLastKnownLocation(currentProvider);
053             if(currentLocation != null){
054                 Log.d("Location""Latitude: " + currentLocation.getLatitude());
055                 Log.d("Location""location: " + currentLocation.getLongitude());
056                 break;
057             }else{
058                 Log.d("Location""Latitude: " 0);
059                 Log.d("Location""location: " 0);
060             }
061             try {
062                 Thread.sleep(10000);
063             catch (InterruptedException e) {
064                  Log.e("Location", e.getMessage());
065             }
066         }
067          
068         //解析地址并显示
069         Geocoder geoCoder = new Geocoder(this);
070         try {
071             int latitude = (int) currentLocation.getLatitude();
072             int longitude = (int) currentLocation.getLongitude();
073             List<Address> list = geoCoder.getFromLocation(latitude, longitude, 2);
074             for(int i=0; i<list.size(); i++){
075                 Address address = list.get(i);
076                 Toast.makeText(MainActivity.this, address.getCountryName() + address.getAdminArea() + address.getFeatureName(), Toast.LENGTH_LONG).show();
077             }
078         catch (IOException e) {
079             Toast.makeText(MainActivity.this,e.getMessage(), Toast.LENGTH_LONG).show();
080         }
081          
082      }
083       
084      //创建位置监听器
085      private LocationListener locationListener = new LocationListener(){
086          //位置发生改变时调用
087          @Override
088          public void onLocationChanged(Location location) {
089              Log.d("Location""onLocationChanged");
090              Log.d("Location""onLocationChanged Latitude" + location.getLatitude());
091                   Log.d("Location""onLocationChanged location" + location.getLongitude());
092          }
093   
094          //provider失效时调用
095          @Override
096          public void onProviderDisabled(String provider) {
097              Log.d("Location""onProviderDisabled");
098          }
099   
100          //provider启用时调用
101          @Override
102          public void onProviderEnabled(String provider) {
103              Log.d("Location""onProviderEnabled");
104          }
105   
106          //状态改变时调用
107          @Override
108          public void onStatusChanged(String provider, int status, Bundle extras) {
109              Log.d("Location""onStatusChanged");
110          }
111      };
112  }

由于代码里的Criteria对象对位置精度要求并不高,所以一般会返回“network”作为provider,而基于network的定位往往会存在一定的位置偏差,这对于需要精确定位的应用程序来说,显然不合要求。这时,需要则需要用到基于GPS的定位方法了

在实现GPS定位前,先了解一下GPS的部分特性:

  1. GPS定位需要依靠3颗或3颗以上的卫星。

  2. GPS定位受环境影响较大,在晴朗的空地上,较容易搜索到卫星,而在室内通常是无法搜索到卫星的。

  3. GPS定位需要使用GPS功能模块,而GPS功能模块的耗电量是巨大的。

  在Android系统中,实现GPS定位的思路应该是:

  1. 获取GPS的Location Provider。

  2. 讲此Provider传入到requestLocationUpdates()方法,让Android系统获知搜索位置方式。

  3. 创建实现了GpsStatus.Listener接口的对象,重写onGpsStatusChanged()方法,向LocationManager添加次监听器,检测卫星状态。(可选步骤)

001 public class MainActivity extends Activity {
002      private LocationManager locationManager;
003      private GpsStatus gpsstatus;
004      @Override
005      public void onCreate(Bundle savedInstanceState) {
006         super.onCreate(savedInstanceState);
007         setContentView(R.layout.main);
008          
009         //获取到LocationManager对象
010         locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
011          
012         //根据设置的Criteria对象,获取最符合此标准的provider对象
013         String currentProvider = locationManager.getProvider(LocationManager.GPS_PROVIDER).getName();
014          
015         //根据当前provider对象获取最后一次位置信息
016         Location currentLocation = locationManager.getLastKnownLocation(currentProvider);
017         //如果位置信息为null,则请求更新位置信息
018         if(currentLocation == null){
019             locationManager.requestLocationUpdates(currentProvider, 00, locationListener);
020         }
021         //增加GPS状态监听器
022         locationManager.addGpsStatusListener(gpsListener);
023          
024         //直到获得最后一次位置信息为止,如果未获得最后一次位置信息,则显示默认经纬度
025         //每隔10秒获取一次位置信息
026         while(true){
027             currentLocation = locationManager.getLastKnownLocation(currentProvider);
028             if(currentLocation != null){
029                 Log.d("Location""Latitude: " + currentLocation.getLatitude());
030                 Log.d("Location""location: " + currentLocation.getLongitude());
031                 break;
032             }else{
033                 Log.d("Location""Latitude: " 0);
034                 Log.d("Location""location: " 0);
035             }
036             try {
037                 Thread.sleep(10000);
038             catch (InterruptedException e) {
039                  Log.e("Location", e.getMessage());
040             }
041         }
042      }
043       
044      private GpsStatus.Listener gpsListener = new GpsStatus.Listener(){
045          //GPS状态发生变化时触发
046          @Override
047          public void onGpsStatusChanged(int event) {
048              //获取当前状态
049              gpsstatus=locationManager.getGpsStatus(null);
050              switch(event){
051                  //第一次定位时的事件
052                  case GpsStatus.GPS_EVENT_FIRST_FIX:
053                      break;
054                  //开始定位的事件
055                  case GpsStatus.GPS_EVENT_STARTED:
056                      break;
057                  //发送GPS卫星状态事件
058                  case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
059                      Toast.makeText(MainActivity.this"GPS_EVENT_SATELLITE_STATUS", Toast.LENGTH_SHORT).show();
060                      Iterable<GpsSatellite> allSatellites = gpsstatus.getSatellites();  
061                      Iterator<GpsSatellite> it=allSatellites.iterator();
062                      int count = 0;
063                      while(it.hasNext())  
064                      {  
065                          count++;
066                      }
067                      Toast.makeText(MainActivity.this"Satellite Count:" + count, Toast.LENGTH_SHORT).show();
068                      break;
069                  //停止定位事件
070                  case GpsStatus.GPS_EVENT_STOPPED:
071                      Log.d("Location""GPS_EVENT_STOPPED");
072                      break;
073              }
074          }
075      };
076       
077       
078      //创建位置监听器
079      private LocationListener locationListener = new LocationListener(){
080          //位置发生改变时调用
081          @Override
082          public void onLocationChanged(Location location) {
083              Log.d("Location""onLocationChanged");
084          }
085   
086          //provider失效时调用
087          @Override
088          public void onProviderDisabled(String provider) {
089              Log.d("Location""onProviderDisabled");
090          }
091   
092          //provider启用时调用
093          @Override
094          public void onProviderEnabled(String provider) {
095              Log.d("Location""onProviderEnabled");
096          }
097   
098          //状态改变时调用
099          @Override
100          public void onStatusChanged(String provider, int status, Bundle extras) {
101              Log.d("Location""onStatusChanged");
102          }
103      };
104  }

通过以上代码中的注释部分,可以清晰的知道Android定位功能里相关方法的具体含义。希望对大家有用。

  另外,因为GPS的自身特性,此代码在室内几乎无法定位,所以建议再真正的实际项目里,至少使用network和GPS两种不同的Location Provider实现定位功能。


目录
相关文章
|
2月前
|
Android开发
Android开发表情emoji功能开发
本文介绍了一种在Android应用中实现emoji表情功能的方法,通过将图片与表情字符对应,实现在`TextView`中的正常显示。示例代码展示了如何使用自定义适配器加载emoji表情,并在编辑框中输入或删除表情。项目包含完整的源码结构,可作为开发参考。视频演示和源码详情见文章内链接。
74 4
Android开发表情emoji功能开发
|
2月前
|
安全 Android开发 iOS开发
Android vs iOS:探索移动操作系统的设计与功能差异###
【10月更文挑战第20天】 本文深入分析了Android和iOS两个主流移动操作系统在设计哲学、用户体验、技术架构等方面的显著差异。通过对比,揭示了这两种系统各自的独特优势与局限性,并探讨了它们如何塑造了我们的数字生活方式。无论你是开发者还是普通用户,理解这些差异都有助于更好地选择和使用你的移动设备。 ###
55 3
|
3月前
|
Java 测试技术 Android开发
Android性能测试——发现和定位内存泄露和卡顿
本文详细介绍了Android应用性能测试中的内存泄漏与卡顿问题及其解决方案。首先,文章描述了使用MAT工具定位内存泄漏的具体步骤,并通过实例展示了如何分析Histogram图表和Dominator Tree。接着,针对卡顿问题,文章探讨了其产生原因,并提供了多种测试方法,包括GPU呈现模式分析、FPS Meter软件测试、绘制圆点计数法及Android Studio自带的GPU监控功能。最后,文章给出了排查卡顿问题的四个方向,帮助开发者优化应用性能。
207 4
Android性能测试——发现和定位内存泄露和卡顿
|
4月前
|
编解码 测试技术 Android开发
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
本文详细介绍了如何利用CameraX库实现高质量的照片及视频拍摄功能,包括添加依赖、初始化、权限请求、配置预览与捕获等关键步骤。此外,还特别针对不同分辨率和帧率的视频拍摄提供了性能优化策略,确保应用既高效又稳定。
414 1
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
|
3月前
|
Android开发 开发者
Android平台无纸化同屏如何实现实时录像功能
Android平台无纸化同屏,如果需要本地录像的话,实现难度不大,只要复用之前开发的录像模块的就可以,对我们来说,同屏采集这块,只是数据源不同而已,如果是自采集的其他数据,我们一样可以编码录像。
|
4月前
|
图形学 Android开发
小功能⭐️Unity调用Android常用事件
小功能⭐️Unity调用Android常用事件
|
6月前
|
数据库 Android开发 数据安全/隐私保护
在 Android Studio 中结合使用 SQLite 数据库实现简单的注册和登录功能
在 Android Studio 中结合使用 SQLite 数据库实现简单的注册和登录功能
270 2
|
6月前
|
Android开发
Android中如何快速的实现RecycleView的拖动重排序功能
使用`ItemTouchHelper`和自定义`Callback`,在`RecyclerView`中实现拖动排序功能。定义`ItemTouchHelperAdapter`接口,`Adapter`实现它以处理`onItemMove`方法。`SimpleItemTouchHelperCallback`设置拖动标志,如`LEFT`或`RIGHT`(水平拖动),并绑定到`RecyclerView`以启用拖动。完成这些步骤后,即可实现拖放排序。关注公众号“AntDream”获取更多内容。
126 3
|
7月前
|
移动开发 监控 Android开发
构建高效Android应用:从内存优化到电池寿命代码之美:从功能实现到艺术创作
【5月更文挑战第28天】 在移动开发领域,特别是针对Android系统,性能优化始终是关键议题之一。本文深入探讨了如何通过细致的内存管理和电池使用策略,提升Android应用的运行效率和用户体验。文章不仅涵盖了现代Android设备上常见的内存泄漏问题,还提出了有效的解决方案,包括代码级优化和使用工具进行诊断。同时,文中也详细阐述了如何通过减少不必要的后台服务、合理管理设备唤醒锁以及优化网络调用等手段延长应用的电池续航时间。这些方法和技术旨在帮助开发者构建更加健壮、高效的Android应用程序。
|
7月前
|
Android开发 数据安全/隐私保护 iOS开发
ios和安卓测试包发布网站http://fir.im的注册与常用功能
ios和安卓测试包发布网站http://fir.im的注册与常用功能
319 0
ios和安卓测试包发布网站http://fir.im的注册与常用功能