在Android上获取用户当前位置的最简单和最稳健的方法是什么?

编程入门 行业动态 更新时间:2024-10-08 22:49:46
本文介绍了在Android上获取用户当前位置的最简单和最稳健的方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

Android上的 LocationManager API看起来对于仅需要偶尔粗略近似用户位置的应用程序来说有点麻烦。

我正在开发的应用程序本身并不是一个位置应用程序,但它确实需要获取用户的位置才能显示附近的商家列表。它不需要担心用户是否正在移动或类似的东西。

以下是我想要做的:

  • 向用户显示附近位置列表。
  • 预先加载用户的位置,以便在我需要的时候在 Activity X,它将可用。 我并不特别关心更新的准确性或频率。只要抓住一个位置就足够了,只要它不离开。也许如果我想要看起来我会每隔几分钟更新一次位置,但这不是一个巨大的优先事项。
  • 只要任何设备具有GPS或网络位置提供商。
  • 好像它不应该那么难,但在我看来,我必须旋转建立两个不同的位置提供商(GPS和NETWORK)并管理每个生命周期。不仅如此,我还必须在多个活动中复制相同的代码才能满足#2。过去,我尝试过使用 getBestProvider()来将解决方案简化为只使用一个位置提供者,但这似乎只给你最好的理论提供者而不是实际上会给你带来最好结果的提供商。

    有没有更简单的方法来完成这项工作?

  • 首先,我检查启用了哪些提供程序。有些可能在设备上被禁用,有些可能在应用程序清单中被禁用。
  • 如果有任何提供程序可用,则启动位置侦听程序和超时定时器。在我的例子中,这是20秒,可能不足以支持GPS,因此您可以放大它。
  • 如果我从位置侦听器获取更新,则使用提供的值。我停止侦听器和计时器。
  • 如果我没有得到任何更新和计时器,我必须使用上次已知的值。
  • 已知的可用提供者的值并选择最近的值。

    以下是我如何使用我的类:

    LocationResult locationResult = new LocationResult(){ @Override public void gotLocation(Location location){ // Got那个地点! } }; MyLocation myLocation = new MyLocation(); myLocation.getLocation(this,locationResult);

    以下是MyLocation类:

    import java.util.Timer; import java.util.TimerTask; 导入android.content.Context; 导入android.location.Location; 导入android.location.LocationListener; 导入android.location.LocationManager; 导入android.os.Bundle; public class MyLocation { Timer timer1; LocationManager lm; LocationResult locationResult; 布尔值gps_enabled = false; 布尔值network_enabled = false; public boolean getLocation(Context context,LocationResult result) { //我使用LocationResult回调类将位置值从MyLocation传递给用户代码。 locationResult = result; if(lm == null) lm =(LocationManager)context.getSystemService(Context.LOCATION_SERVICE); //如果提供者不被允许,将抛出异常。 try {gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);} catch(Exception ex){} try {network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);} catch(Exception ex){} //如果没有启用提供程序,则不启动监听程序 if(!gps_enabled&< network_enabled) return false; if(gps_enabled) lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,locationListenerGps); if(network_enabled) lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0,0,locationListenerNetwork); timer1 = new Timer(); timer1.schedule(new GetLastLocation(),20000); 返回true; LocationListener locationListenerGps = new LocationListener(){ public void onLocationChanged(Location location){ timer1.cancel(); locationResult.gotLocation(location); lm.removeUpdates(this); lm.removeUpdates(locationListenerNetwork); } public void onProviderDisabled(String provider){} $ b $ public void onProviderEnabled(String provider){} $ b $ public void onStatusChanged(String provider,int status,Bundle extras){} }; LocationListener locationListenerNetwork = new LocationListener(){ public void onLocationChanged(Location location){ timer1.cancel(); locationResult.gotLocation(location); lm.removeUpdates(this); lm.removeUpdates(locationListenerGps); } public void onProviderDisabled(String provider){} $ b $ public void onProviderEnabled(String provider){} $ b $ public void onStatusChanged(String provider,int status,Bundle extras){} }; $ b $ class GetLastLocation extends TimerTask { @Override public void run(){ lm.removeUpdates(locationListenerGps); lm.removeUpdates(locationListenerNetwork); 位置net_loc = null,gps_loc = null; if(gps_enabled) gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); if(network_enabled) net_loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); (gps_loc!= null&& net_loc!= null){ if(gps_loc.getTime()) //如果两个值都使用最新的, > net_loc.getTime()) locationResult.gotLocation(gps_loc); else locationResult.gotLocation(net_loc); return; } if(gps_loc!= null){ locationResult.gotLocation(gps_loc); return; } if(net_loc!= null){ locationResult.gotLocation(net_loc); return; } locationResult.gotLocation(null); } } public static abstract class LocationResult { public abstract void gotLocation(Location location); } }

    有人可能也想修改我的逻辑。例如,如果你从网络提供商那里得到更新,不要停止监听,而是继续等待。 GPS提供更准确的数据,因此值得等待。如果计时器已过,并且您已从网络获取更新,但无法从GPS获得更新,则可以使用Network提供的值。 developer.android/training/location/retrieve-current.html =noreferrer> developer.android/training/location/retrieve-current.html 。但它需要将Google Play服务apk安装在用户设备上。

    The LocationManager API on Android seems like it's a bit of a pain to use for an application that only needs an occasional and rough approximation of the user's location.

    The app I'm working on isn't really a location app per se, but it does need to get the user's location in order to display a list of nearby businesses. It doesn't need to worry about if the user is moving around or anything like that.

    Here's what I'd like to do:

  • Show the user a list of nearby locations.
  • Preload the user's location so that by the time I need it in Activity X, it will be available.
  • I don't particularly care about accuracy or frequency of update. Just grabbing one location is sufficient as long as it's not way off. Maybe if I want to be fancy I'll update the location once every few mins or so, but it's not a huge priority.
  • Work for any device as long as it has either a GPS or a Network Location provider.
  • It seems like it shouldn't be that hard, but it appears to me that I have to spin up two different location providers (GPS and NETWORK) and manage each's lifecycle. Not only that, but I have to duplicate the same code in multiple activities to satisfy #2. I've tried using getBestProvider() in the past to cut the solution down to just using one location provider, but that seems to only give you the best "theoretical" provider rather than the provider that's actually going to give you the best results.

    Is there a simpler way to accomplish this?

    解决方案

    Here's what I do:

  • First of all I check what providers are enabled. Some may be disabled on the device, some may be disabled in application manifest.
  • If any provider is available I start location listeners and timeout timer. It's 20 seconds in my example, may not be enough for GPS so you can enlarge it.
  • If I get update from location listener I use the provided value. I stop listeners and timer.
  • If I don't get any updates and timer elapses I have to use last known values.
  • I grab last known values from available providers and choose the most recent of them.
  • Here's how I use my class:

    LocationResult locationResult = new LocationResult(){ @Override public void gotLocation(Location location){ //Got the location! } }; MyLocation myLocation = new MyLocation(); myLocation.getLocation(this, locationResult);

    And here's MyLocation class:

    import java.util.Timer; import java.util.TimerTask; import android.content.Context; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; public class MyLocation { Timer timer1; LocationManager lm; LocationResult locationResult; boolean gps_enabled=false; boolean network_enabled=false; public boolean getLocation(Context context, LocationResult result) { //I use LocationResult callback class to pass location value from MyLocation to user code. locationResult=result; if(lm==null) lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); //exceptions will be thrown if provider is not permitted. try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){} try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){} //don't start listeners if no provider is enabled if(!gps_enabled && !network_enabled) return false; if(gps_enabled) lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps); if(network_enabled) lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork); timer1=new Timer(); timer1.schedule(new GetLastLocation(), 20000); return true; } LocationListener locationListenerGps = new LocationListener() { public void onLocationChanged(Location location) { timer1.cancel(); locationResult.gotLocation(location); lm.removeUpdates(this); lm.removeUpdates(locationListenerNetwork); } public void onProviderDisabled(String provider) {} public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extras) {} }; LocationListener locationListenerNetwork = new LocationListener() { public void onLocationChanged(Location location) { timer1.cancel(); locationResult.gotLocation(location); lm.removeUpdates(this); lm.removeUpdates(locationListenerGps); } public void onProviderDisabled(String provider) {} public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extras) {} }; class GetLastLocation extends TimerTask { @Override public void run() { lm.removeUpdates(locationListenerGps); lm.removeUpdates(locationListenerNetwork); Location net_loc=null, gps_loc=null; if(gps_enabled) gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); if(network_enabled) net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); //if there are both values use the latest one if(gps_loc!=null && net_loc!=null){ if(gps_loc.getTime()>net_loc.getTime()) locationResult.gotLocation(gps_loc); else locationResult.gotLocation(net_loc); return; } if(gps_loc!=null){ locationResult.gotLocation(gps_loc); return; } if(net_loc!=null){ locationResult.gotLocation(net_loc); return; } locationResult.gotLocation(null); } } public static abstract class LocationResult{ public abstract void gotLocation(Location location); } }

    Somebody may also want to modify my logic. For example if you get update from Network provider don't stop listeners but continue waiting. GPS gives more accurate data so it's worth waiting for it. If timer elapses and you've got update from Network but not from GPS then you can use value provided from Network.

    One more approach is to use LocationClient developer.android/training/location/retrieve-current.html. But it requires Google Play Services apk to be installed on user device.

    更多推荐

    在Android上获取用户当前位置的最简单和最稳健的方法是什么?

    本文发布于:2023-10-19 17:39:27,感谢您对本站的认可!
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:当前位置   最简单   稳健   方法   用户

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!