定位服务API案例
定位服务API案例
要使用定位服务API,需要确保设备已经下载并安装了HMS Core服务组件,并将Location Kit的SDK集成到项目中。
指定应用权限
- Android提供了两种位置权限: ACCESS_COARSE_LOCATION(粗略的位置权限)和ACCESS_FINE_LOCATION(精确的位置权限)。需要在“AndroidManifest.xml”文件中申请权限:
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
- 在Android Q版本中,如果需要应用程序在后台执行时也具备持续定位能力,需要在“AndroidManifest.xml”文件中申请ACCESS_BACKGROUND_LOCATION权限:
- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
- 在“AndroidManifest.xml”中添加后,还要在代码中动态申请一下权限(Android 6.0危险权限要求):
- // Android SDK<=28 所需权限动态申请
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
- Log.i(TAG, "android sdk <= 28 Q");
- if (ActivityCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
- && ActivityCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- String[] strings =
- {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
- 10. ActivityCompat.requestPermissions(this, strings, 1);
- 11. }
12. } else {
- 13. // Android SDK>28 所需权限动态申请,需添加“android.permission.ACCESS_BACKGROUND_LOCATION”权限
- 14. if (ActivityCompat.checkSelfPermission(this,
- 15. Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
- 16. && ActivityCompat.checkSelfPermission(this,
- 17. Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
- 18. && ActivityCompat.checkSelfPermission(this,
- 19. "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
- 20. String[] strings = {android.Manifest.permission.ACCESS_FINE_LOCATION,
- 21. android.Manifest.permission.ACCESS_COARSE_LOCATION,
- 22. "android.permission.ACCESS_BACKGROUND_LOCATION"};
- 23. ActivityCompat.requestPermissions(this, strings, 2);
- 24. }
25. }
创建定位服务客户端
在项目中使用到定位服务的Activity中的onCreate()方法中创建一个FusedLocationProviderClient实例,通过该实例调用定位相关接口。
- // 定位交互接入对象
- private FusedLocationProviderClient fusedLocationProviderClient;
- // 定位请求信息对象
- private LocationRequest mLocationRequest;
- protected void onCreate(Bundle savedInstanceState) {
- fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
- }
说明
当传入参数为非Activity类型时,如果使用FusedLocationProviderClient实例调用定位服务接口发生异常,就不会弹出UI交互界面提示用户处理,只会返回错误码。例如:当HMS Core不符合定位服务的版本要求时,便会返回错误码907135003,此时需要手动升级HMS Core。如果需要拉起升级引导界面,建议传入Activity类型参数替代Context类型,创建FusedLocationProviderClient实例。
检查设备定位设置
设备的相关定位设置会影响定位服务的定位结果,例如位置开关选项处于关闭状态时,将无法获取到位置信息。因此,建议在持续获取位置信息之前,先检查设备设置是否满足定位条件。定位服务提供了检查设备定位相关设置的能力,通过LocationServices的getSettingsClient(Activity activity)获取SettingsClient实例,然后调用checkLocationSettings(LocationSettingsRequest locationSettingsRequest)接口获取定位设置结果,当设置不满足定位条件时,可以调用startResolutionForResult接口用于弹框提示用户打开对应的权限(HMS Core 定位权限必须打开,Android Q版本必须选择“始终允许”)。
- 调用getSettingsClient()接口获取SettingsClient实例。
- SettingsClient settingsClient = LocationServices.getSettingsClient(this);
- 调用checkLocationSettings()检查设备设置。
- LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
- mLocationRequest = new LocationRequest();
- builder.addLocationRequest(mLocationRequest);
- LocationSettingsRequest locationSettingsRequest = builder.build();
- // 检查设备定位设置
- settingsClient.checkLocationSettings(locationSettingsRequest)
- // 检查设备定位设置接口成功监听回调
- .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
- @Override
- 10. public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
- 11. // 设置满足定位条件,再发起位置请求
- 12. fusedLocationProviderClient
- 13. .requestLocationUpdates(mLocationRequest, mLocationCallback,Looper.getMainLooper())
- 14. // 请求位置更新接口成功监听回调
- 15. .addOnSuccessListener(new OnSuccessListener<Void>() {
- 16. @Override
- 17. public void onSuccess(Void aVoid) {
- 18. // ...
- 19. }
- 20. });
- 21. }
- 22. })
- 23. // 检查设备定位设置接口失败监听回调
- 24. .addOnFailureListener(new OnFailureListener() {
- 25. @Override
- 26. public void onFailure(Exception e) {
- 27. // 设置不满足定位条件
- 28. int statusCode = ((ApiException) e).getStatusCode();
- 29. switch (statusCode) {
- 30. case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
- 31. try {
- 32. ResolvableApiException rae = (ResolvableApiException) e;
- 33. // 调用startResolutionForResult可以弹窗提示用户打开相应权限
- 34. rae.startResolutionForResult(MainActivity.this, 0);
- 35. } catch (IntentSender.SendIntentException sie) {
- 36. // …
- 37. }
- 38. break;
- 39. }
- 40. }
- 41. });
持续获取位置信息
如果希望应用可以持续获取设备位置,可以使用定位服务提供的requestLocationUpdates()接口。该接口根据入参形式的不同,将以两种不同的形式将位置信息返回。一种是通过调用已经定义的LocationCallback类中onLocationResult()回调方法返回一个包含位置信息的LocationResult对象,另一种是将位置信息置于PendingIntent扩展信息中返回。
当应用程序不再需要接收位置更新时,应当停止位置更新,以便于降低功耗。要停止位置更新,可以调用removeLocationUpdates(),传入与requestLocationUpdates()接口相对应的LocationCallback或PendingIntent对象。这里以回调方式作为样例,代码如下。详细的参数说明请参见LocationService接口说明。
- 设置持续定位请求参数。
- LocationRequest mLocationRequest = new LocationRequest();
- // 设置位置更新的间隔(单位为毫秒)
- mLocationRequest.setInterval(10000);
- // 设置定位类型
- mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
- 定义位置更新回调。
- LocationCallback mLocationCallback;
- mLocationCallback = new LocationCallback() {
- @Override
- public void onLocationResult(LocationResult locationResult) {
- if (locationResult != null) {
- // 处理位置回调结果
- }
- }
- };
- 调用requestLocationUpdates()进行持续定位。
- fusedLocationProviderClient
- .requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- // 接口调用成功的处理
- }
- })
- .addOnFailureListener(new OnFailureListener() {
- 10. @Override
- 11. public void onFailure(Exception e) {
- 12. // 接口调用失败的处理
- 13. }
- 14. });
说明
如果接口调用成功,获取位置信息失败,请参见接口调用成功,获取不到位置信息。
- 调用removeLocationUpdates()停止位置更新。
- // 注意:停止位置更新时,mLocationCallback必须与requestLocationUpdates方法中的LocationCallback参数为同一对象。
- fusedLocationProviderClient.removeLocationUpdates(mLocationCallback)
- // 停止位置更新成功监听回调
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- //...
- }
- })
- 10. // 停止位置更新失败监听回调
- 11. .addOnFailureListener(new OnFailureListener() {
- 12. @Override
- 13. public void onFailure(Exception e) {
- 14. // ...
- 15. }
- 16. });
获取最后的已知位置
应用可以调用getLastLocation()方法获取设备最后的已知位置,大多情况下,该位置即为设备的当前位置。代码样例如下:
- // 获取最后的已知位置
- Task<Location> task = fusedLocationProviderClient.getLastLocation()
- // 获取最后的已知位置成功监听回调
- .addOnSuccessListener(new OnSuccessListener<Location>() {
- @Override
- public void onSuccess(Location location) {
- if (location == null) {
- return;
- }
- 10. // 成功时Location对象处理逻辑
- 11. // ...
- 12. }
- 13. })
- 14. // 获取最后的已知位置失败监听回调
- 15. .addOnFailureListener(new OnFailureListener() {
- 16. @Override
- 17. public void onFailure(Exception e) {
- 18. // ...
- 19. }
- 20. });
说明
getLastLocation()方法是从系统缓存中获取位置信息的。如果获取的位置信息为null,则可能是系统缓存已经被清除;此时先调用requestLocationUpdates()方法获取位置信息以刷新缓存,再调用getLastLocation()方法即可以获取到位置信息。
使用模拟位置信息功能
具体操作步骤:打开“设置 > 系统和更新 > 开发人员选项 > 选择模拟位置信息应用 > 选择要模拟位置信息应用”(如果没有发现“开发人员选项”,请执行如下操作:“设置 > 关于手机 > 版本号”,连续点击“版本号”7次,“开发人员选项”会出现在“系统与更新”页面,再重复上述操作),代码开发步骤如下:
- 在AndroidManifest.xml文件中配置模拟定位权限。
- <uses-permission
- android:name="android.permission.ACCESS_MOCK_LOCATION"
- tools:ignore="MockLocation,ProtectedPermissions" />
- 设置mock模式,调用setMockMode(boolean isMockMode)。
- // 设置mock模式,参数传入ture:模拟模式;false:正常状态
- boolean mockFlag = true;
- fusedLocationProviderClient.setMockMode(mockFlag)
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- Log.i(TAG, "setMockMode onSuccess");
- }
- })
- 10. .addOnFailureListener(new OnFailureListener() {
- 11. @Override
- 12. public void onFailure(Exception e) {
- 13. Log.i(TAG, "setMockMode onFailure:" + e.getMessage());
- 14. }
- 15. });
- 设置模拟位置信息,调用setMockLocation(Location mockLocation)。
- // 设置模拟位置信息
- final Location mockLocation = new Location(LocationManager.GPS_PROVIDER);
- mockLocation.setLongitude(118.76);
- mockLocation.setLatitude(31.98);
- fusedLocationProviderClient.setMockLocation(mockLocation)
- // 设置模拟位置信息成功监听回调
- .addOnSuccessListener(new OnSuccessListener<Void>() {
- @Override
- public void onSuccess(Void aVoid) {
- 10. Log.i(TAG, "setMockLocation onSuccess");
- 11. }
- 12. })
- 13. // 设置模拟位置信息失败监听回调
- 14. .addOnFailureListener(new OnFailureListener() {
- 15. @Override
- 16. public void onFailure(Exception e) {
- 17. Log.i(TAG, "setMockLocation onFailure:" + e.getMessage());
- 18. }
- 19. });
定位服务API案例的更多相关文章
- 【Android】18.2 利用百度定位服务API实现位置跟踪
分类:C#.Android.VS2015: 创建日期:2016-03-04 一.简介 第3章已经介绍过百度定位SDK,这里再演示一遍其基本用法. 二.示例2-百度定位服务基本用法 运行截图 设计步骤 ...
- iOS6定位服务编程详解
现在的移动设备很多都提供定位服务,使用iOS系统的iPhone.iPod Touch和iPad都可以提供位置服务,iOS设备能提供3种不同途径进行定位:Wifi, 蜂窝式移动电话基站, GPS卫星 i ...
- iOS定位服务编程详解
现在的移动设备很多都提供定位服务,使用iOS系统的iPhone.iPod Touch和iPad都可以提供位置服务,iOS设备能提供3种不同途径进行定位:Wifi, 蜂窝式移动电话基站, GPS卫星 i ...
- 【Android】18.1 利用安卓内置的定位服务实现位置跟踪
分类:C#.Android.VS2015: 创建日期:2016-03-04 一.安卓内置的定位服务简介 通常将各种不同的定位技术称为位置服务或定位服务.这种服务是通过电信运营商的无线电通信网络(如GS ...
- 【iOS】7.4 定位服务->2.1.4 定位 - 官方框架CoreLocation 案例:指南针效果
本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...
- 【iOS】7.4 定位服务->3.1 地图框架MapKit 功能1:地图展示
> 本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. --- > 本文相关目录: ================== 所属文集:[[ ...
- [android学习]android_gps定位服务简单实现
前言 gps定位服务的学习是这段时间gps课程的学习内容,之前老师一直在将概念,今天终于是实践课(其实就是给了一个案例,让自己照着敲).不过在照着案列敲了两遍之后,发现老师的案例是在是太老了,并且直接 ...
- IOS 定位服务与地图的应用开发
1.定位服务 现在的移动设备很多都提供定位服务,IOS设备提供3种不同定位途径: (1)WiFi定位,通过查询一个WiFi路由器的地理位置的信息,比较省电:IPhone,IPod touch和IPad ...
- Push Notification总结系列之移动客户端定位服务
Push Notification系列概括: 1.Push Notification简介和证书说明及生成配置 2.Push Notification的iOS处理代码和Provider详解 3.Push ...
随机推荐
- 12- APP接口测试以及接口文档的分析
什么是接口? 为什么要做接口测试? 接口测试流程 需求评审 需求分析 接口用例设计 执行测试用例 bug的定位于追踪 接口文档分析 接口文档分析:开发 内容: 1.接口名称 2.接口地址 3.支持方式 ...
- PHP生成随机数的几种方法
第一种方法用mt_rand() function GetRandStr($length){ $str='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV ...
- hdu1556 线段树段更新(简单题)
题意: N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的"小飞鸽"牌电动车从气球a开始到气球b依次给每个 ...
- POJ3040给奶牛发工资
题意: 有n种硬币,每种硬币有mi个,然后让你给奶牛发工资,每周发至少c元(就是不找零钱的意思)然后问你能发几周?(硬币之间都是倍数关系) 思路: 这个题目做了两天,丢脸,看完 ...
- Win64 驱动内核编程-29.强制解锁文件
强制解锁文件 强制解锁因其他进程占用而无法删除的文件. 1.调用 ZwQuerySystemInformation 的 16 功能号来枚举系统里的句柄 2.打开拥有此句柄的进程并把此句柄复制到自己的进 ...
- layui中的视频上传(PHP )
1.html中: <div class="layui-form-item"> <label class="layui-form-label"& ...
- Java 并发编程(一) → LockSupport 详解
开心一刻 今天突然收到花呗推送的消息,说下个月 9 号需要还款多少钱 我就纳了闷了,我很长时间没用花呗了,怎么会欠花呗钱? 后面我一想,儿子这几天玩了我手机,是不是他偷摸用了我的花呗 于是我找到儿子问 ...
- 03.28,周六,12:00-17:00,ICPC训练联盟周赛,选用试题:UCF Local Programming Contest 2016正式赛。
A. Majestic 10 题意:三个数均大于10则输出"triple-double",如果两个数大于10则输出"double-double",如果一个大于1 ...
- Python编写abaqus后处理脚本(学习笔记)
本节内容参考自书籍<Python语言在Abaqus中的应用>,注意:以下代码为伪代码,仅供参考 1.导入必要的模块,加载后处理odb文件 from abaqus import * from ...
- 吃透KVM创建虚机和KVM命令
1.创建虚拟机 1.1创建虚拟机磁盘 #使用qemu命令来创建磁盘 qemu-img create -f qcow2 /var/lib/libvirt/images/centos7.2.qcow2 2 ...