草庐IT

安卓 : LocationManager vs Google Play Services

coder 2023-05-07 原文

我想构建一个以获取用户当前位置为中心的应用程序,然后通过 找到他/她附近的兴趣点(例如酒吧、餐厅等)。 Google Places API .

在网上搜索开始的地方时,我发现了一些使用 LocationManager 的教程。类和其他一些使用 Google Play 服务 为了找到用户的位置。

乍一看,他们都做同样的事情,但由于我是新手,所以我有点困惑,我不知道哪种方法最适合我的需要。所以,我想问你:

这两种查找位置的方法(如果有的话)有什么区别?

最佳答案

Android 上的用户位置

在 Android 上获取用户的位置比在 iOS 上要简单一些。要开始混淆,您可以通过两种完全不同的方式来做到这一点。第一个是使用来自 android.location.LocationListener 的 Android API。 ,第二个是使用 Google Play 服务 API com.google.android.gms.location.LocationListener .让我们来看看它们。

  • Android 的位置 API

    Android 的位置 API 使用三个不同的提供程序来获取位置 -
  • LocationManager.GPS_PROVIDER — 该提供商使用卫星确定位置。根据条件,此提供程序可能需要一段时间才能返回位置修复。
  • LocationManager.NETWORK_PROVIDER — 该提供商根据蜂窝塔和 WiFi 接入点的可用性确定位置。通过网络查找检索结果。
  • LocationManager.PASSIVE_PROVIDER — 此提供程序将返回其他提供程序生成的位置。当其他应用程序或服务请求位置更新时,您会被动地接收位置更新,而无需您自己实际请求位置。

  • 它的要点是你得到一个 LocationManager 的对象。从系统,实现 LocationListener ,并调用 requestLocationUpdatesLocationManager .

    这是一个代码 fragment :
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    // Define a listener that responds to location updates
    LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
          // Called when a new location is found by the network location provider.
          makeUseOfNewLocation(location);
        }
    
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    
        public void onProviderEnabled(String provider) {}
    
        public void onProviderDisabled(String provider) {}
      };
    
    // Register the listener with the Location Manager to receive location updates
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    

    Google’s API Guide on Location Strategies很好地解释了代码。但他们也提到,在大多数情况下,通过使用 Google Location Services API,您将获得更好的电池性能以及更合适的准确度。反而。现在困惑开始了!
  • Google 的位置服务 API

  • Google 的位置服务 API 是 Google Play 服务 APK (here’s how to set it up) 的一部分。它们建立在 Android 的 API 之上。这些 API 提供了一个“融合位置提供者”,而不是上面提到的提供者。此提供程序会根据准确性、电池使用情况等自动选择要使用的底层提供程序。速度很快,因为您可以从不断更新的系统范围服务中获取位置信息。您还可以使用更高级的功能,例如地理围栏。

    要使用 Google 的定位服务,您的应用需要连接到 GooglePlayServicesClient .要连接到客户端,您的 Activity (或 fragment 等)需要实现 GooglePlayServicesClient.ConnectionCallbacksGooglePlayServicesClient.OnConnectionFailedListener接口(interface)。
    这是一个示例代码:
        public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener {
        LocationClient locationClient;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my);
            locationClient = new LocationClient(this, this, this);
        }
    
        @Override
        public void onConnected(Bundle bundle) {
        Location location = locationClient.getLastLocation() ;
            Toast.makeText(this, "Connected to Google Play Services", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onDisconnected() {
        Toast.makeText(this, "Connected from Google Play Services.", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onConnectionFailed(ConnectionResult connectionResult) {
            // code to handle failed connection
            // this code can be found here — http://developer.android.com/training/location/retrieve-current.html 
        }
    
  • 为什么是 locationClient.getLastLocation()空?
  • locationClient.getLastLocation()从客户端获取最后一个已知位置。但是,如果至少有一个客户端连接到 Fused Location Provider,它只会维护后台位置。一旦第一个客户端连接,它将立即尝试获取位置。如果您的 Activity 是第一个连接的客户端并且您调用 getLastLocation()马上在 onConnected() ,这可能不足以让第一个位置进入。这将导致 location正在 null .

    要解决此问题,您必须(不确定地)等待提供商获取位置,然后调用 getLastLocation() ,这是不可能知道的。另一个(更好)的选择是实现 com.google.android.gms.location.LocationListener接收定期位置更新的界面(并在获得第一次更新后将其关闭)。
        public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
        // . . . . . . . . more stuff here 
        LocationRequest locationRequest;
        LocationClient locationClient;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // . . . . other initialization code
            locationClient = new LocationClient(this, this, this);
        locationRequest = new LocationRequest();
        // Use high accuracy
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            // Set the update interval to 5 seconds
        locationRequest.setInterval(UPDATE_INTERVAL);
            // Set the fastest update interval to 1 second
        locationRequest.setFastestInterval(FASTEST_INTERVAL);
        }
        // . . . . . . . . other methods 
        @Override
        public void onConnected(Bundle bundle) {
            Location location = locationClient.getLastLocation();
            if (location == null)
                locationClient.requestLocationUpdates(locationRequest, this);
            else
                Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
        }
        // . . . . . . . . other methods
        @Override
        public void onLocationChanged(Location location) {
            locationClient.removeLocationUpdates(this);
            // Use the location here!!!
        }
    

    在此代码中,您正在检查客户端是否已经拥有最后一个位置(在 onConnected 中)。如果没有,您正在请求位置更新,并在收到更新后立即关闭请求(在 onLocationChanged() 回调中)。

    请注意 locationClient.requestLocationUpdates(locationRequest, this);必须在 onConnected 内回调,否则你会得到一个 IllegalStateException因为您将尝试在未连接到 Google Play 服务客户端的情况下请求位置。
  • 用户已禁用定位服务

  • 很多时候,用户会禁用位置服务(以节省电池电量或出于隐私原因)。在这种情况下,上面的代码仍然会请求位置更新,但是 onLocationChanged永远不会被调用。您可以通过检查用户是否禁用了位置服务来停止请求。

    如果您的应用需要它们启用定位服务,您可能需要显示一条消息或 toast 。不幸的是,没有办法检查用户是否在 Google 的位置服务 API 中禁用了位置服务。为此,您将不得不求助于 Android 的 API。

    在您的 onCreate方法:
        LocationManager manager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
    if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
        locationEnabled = false;
        Toast.makeText(getActivity(), "Enable location services for accurate data", Toast.LENGTH_SHORT).show();
    }
    else locationEnabled = true;
    

    并使用 locationEnabled您的旗帜 onConnected像这样的方法:
        if (location != null) {
        Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
    }
    else if (location == null && locationEnabled) {
        locationClient.requestLocationUpdates(locationRequest, this);
    }
    

    更新

    文档已更新,LocationClient 已删除,api 支持从对话框中一键启用 GPS:
    task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
    @Override
    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
        // All location settings are satisfied. The client can initialize
        // location requests here.
        // ...
    }
    });
    
    task.addOnFailureListener(this, new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            if (e instanceof ResolvableApiException) {
                // Location settings are not satisfied, but this can be fixed
                // by showing the user a dialog.
                try {
                    // Show the dialog by calling startResolutionForResult(),
                    // and check the result in onActivityResult().
                    ResolvableApiException resolvable = (ResolvableApiException) e;
                    resolvable.startResolutionForResult(MainActivity.this,
                            REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException sendEx) {
                    // Ignore the error.
                }
            }
        }
    });
    

    友情链接 https://developer.android.com/training/location/change-location-settings#prompt

    新位置客户端:FusedLocationProviderClient
      private FusedLocationProviderClient fusedLocationClient;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    }
    

    建议通过https://developer.android.com/training/location在执行任何定位任务之前。

    关于安卓 : LocationManager vs Google Play Services,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33022662/

    有关安卓 : LocationManager vs Google Play Services的更多相关文章

    1. 使用canal同步MySQL数据到ES - 2

      文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

    2. ES基础入门 - 2

      ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

    3. 安卓apk修改(Android反编译apk) - 2

      最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

    4. 关于ES集群信息的一些查看 - 2

      文章目录查看ES信息查看节点信息查看分片信息实际场景下ES分片及副本数量应该怎么分关于ES的灵活使用查看ES信息查看版本kibana:GET/查看节点信息GET/_cat/nodes?v解释:ip:集群中节点的ip地址;heap.percent:堆内存的占用百分比;ram.percent:总内存的占用百分比,其实这个不是很准确,因为buff/cache和available也被当作使用内存;cpu:cpu占用百分比;load_1m:1分钟内cpu负载;load_5m:5分钟内cpu负载;load_15m:15分钟内cpu负载;node.role:上图的dilmrt代表全部权限master:*代表

    5. linux查看es节点使用情况,elasticsearch(es) 如何查看当前集群中哪个节点是主节点(master) - 2

      elasticsearch查看当前集群中的master节点是哪个需要使用_cat监控命令,具体如下。查看方法es主节点确定命令,以kibana上查看示例如下:GET_cat/nodesv返回结果示例如下:ipheap.percentram.percentcpuload_1mload_5mload_15mnode.rolemastername172.16.16.188529952.591.701.45mdi-elastic3172.16.16.187329950.990.991.19mdi-elastic2172.16.16.231699940.871.001.03mdi-elastic4172

    6. 五-1、elasticsearch集群搭建(ES集群搭建) - 2

      目录一、下载Elasticsearch1.选择你要下载的Elasticsearch版本二、采用通用搭建集群的方法三、配置三台es1.上传压缩包到任意一台虚拟机中2.解压并修改配置文件(配置单台es)3.配置三台es集群4.设置后台启动和开机自启(可选)一、下载Elasticsearch1.选择你要下载的Elasticsearch版本es下载地址这里我下载的是二、采用通用搭建集群的方法集群搭建方法三、配置三台es1.上传压缩包到任意一台虚拟机中上传方式有两种第一种:使用xftp上传直接拖动过去就可以了。第二种:使用lrzsz先安装yum-yinstalllrzsz切换到要上传的位置cd/opt/

    7. windows安装es、kibana教程 - 2

      目录前言第一个部分:安装ES的包1.安装成功的截图2.下载es的安装包3.检查本地的jdk的安装是否存在问题4.修改config文件夹下面的配置第二部分:windows安装Kibana可视化工具1.下载安装包2.安装过程中遇到的问题3.安装6.0.0的版本是可以的4.安装后的效果第三部分:安装Elasticsearch-Head进行搜索本地es环境内的所有数据1.下载git项目文件:GitHub-mobz/elasticsearch-head:Awebfrontendforanelasticsearchcluster2.关于kibana不能监控es环境内数据的问题3.重启es的bat文件,使用

    8. (一)专题介绍:移动端安卓手机改造成linux服务器&linux服务器中安装软件、部署前后端分离项目实战 - 2

      快捷目录前言一、涉及到的相关技术简介二、具体实现过程及踩坑杂谈1.安卓手机改造成linux系统实现方案2.改造后的手机Linux中软件的安装3.手机Linux中安装MySQL5.7踩坑实录4.手机Linux中安装软件的正确方法三、Linux服务器部署前后端分离项目流程1.前提准备(安装必要软件,搭建环境):2.前后端分离项目的详细部署过程:总结前言总体概述:本篇文章隶属于“手机改造服务器部署前后端分离项目”系列专栏,该专栏将分多个板块,每个板块独立成篇来详细记录:手机(安卓)改造成个人服务器(Linux)、Linux中安装软件、配置开发环境、部署JAVA+VUE+MySQL5.7前后端分离项目

    9. 优化大数据量查询方案——SpringBoot(Cloud)整合ES - 2

      一、Elasticsearch简介实际业务场景中,多端的查询功能都有很大的优化空间。常见的处理方式有:建索引、建物化视图简化查询逻辑、DB层之上建立缓存、分页…然而随着业务数据量的不断增多,总有那么一张表或一个业务,是无法通过常规的处理方式来缩短查询时间的。在查询功能优化上,作为开发人员应该站在公司的角度,本着优化客户体验的目的去寻找解决方案。本人有幸做过Tomcat整合solr,今天一起研究一下当前比较火热的Elasticsearch搜索引擎。Elasticsearch是一个非常强大的搜索引擎。它目前被广泛地使用于各个IT公司。Elasticsearch是由Elastic公司创建。它的代码位

    10. ES条件查询 - 2

      matchAll分页查询@TestpublicvoidtestMatchAll()throwsIOException{//创建查询请求对象SearchRequestsearchRequest=newSearchRequest("goods");//构建查询条件(分页,查询所有)SearchSourceBuildersearchSourceBuilder=newSearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchAllQuery());//searchSourceBuilder.from(0);searchSour

    随机推荐