在Android上获取用户当前位置的最简单,最强大的方法是什么?LocationManagerAndroid上的API似乎对于仅需要偶尔粗略估计用户位置的应用程序来说有点痛苦。我正在处理的应用程序本身并不是一个位置应用程序,但它确实需要获取用户的位置才能显示附近的商家列表。它不需要担心用户是否在移动或类似的东西。这是我想做的事情:向用户显示附近位置的列表。预加载用户的位置,以便在ActivityX中需要它时,它将可用。我并不特别关心更新的准确性或频率。只要没有办法,抓住一个位置就足够了。也许如果我想要花哨,我会每隔几分钟更新一次位置,但这不是一个重要的优先事项。只要有GPS或网络位置提供商,就可以使用任何设备。看起来它应该不那么难,但在我看来,我必须启动两个不同的位置提供商(GPS和NETWORK)并管理每个生命周期。不仅如此,我还必须在多个活动中复制相同的代码以满足#2。我曾尝试过使用getBestProvider()过去将解决方案缩减为只使用一个位置提供商,但这似乎只能为您提供最好的“理论”提供商,而不是实际上会给您带来最佳结果的提供商。有没有更简单的方法来实现这一目标?
4 回答
![?](http://img1.sycdn.imooc.com/54584f850001c0bc02200220-100-100.jpg)
12345678_0001
TA贡献1802条经验 获得超5个赞
在搜索最佳实现后,如何获得最佳的精确用户位置,我设法结合所有最好的方法,并提出以下类:
/** * Retrieve accurate location from GPS or network services. * * * Class usage example: * * public void onCreate(Bundle savedInstanceState) { * ... * my_location = new MyLocation(); * my_location.init(main.this, locationResult); * } * * * public LocationResult locationResult = new LocationResult(){ * @Override * public void gotLocation(final Location location){ * // do something * location.getLongitude(); * location.getLatitude(); * } * }; */class MyLocation{ /** * If GPS is enabled. * Use minimal connected satellites count. */ private static final int min_gps_sat_count = 5; /** * Iteration step time. */ private static final int iteration_timeout_step = 500; LocationResult locationResult; private Location bestLocation = null; private Handler handler = new Handler(); private LocationManager myLocationManager; public Context context; private boolean gps_enabled = false; private int counts = 0; private int sat_count = 0; private Runnable showTime = new Runnable() { public void run() { boolean stop = false; counts++; System.println("counts=" + counts); //if timeout (1 min) exceeded, stop tying if(counts > 120){ stop = true; } //update last best location bestLocation = getLocation(context); //if location is not ready or don`t exists, try again if(bestLocation == null && gps_enabled){ System.println("BestLocation not ready, continue to wait"); handler.postDelayed(this, iteration_timeout_step); }else{ //if best location is known, calculate if we need to continue to look for better location //if gps is enabled and min satellites count has not been connected or min check count is smaller then 4 (2 sec) if(stop == false && !needToStop()){ System.println("Connected " + sat_count + " sattelites. continue waiting.."); handler.postDelayed(this, iteration_timeout_step); }else{ System.println("#########################################"); System.println("BestLocation finded return result to main. sat_count=" + sat_count); System.println("#########################################"); // removing all updates and listeners myLocationManager.removeUpdates(gpsLocationListener); myLocationManager.removeUpdates(networkLocationListener); myLocationManager.removeGpsStatusListener(gpsStatusListener); sat_count = 0; // send best location to locationResult locationResult.gotLocation(bestLocation); } } } }; /** * Determine if continue to try to find best location */ private Boolean needToStop(){ if(!gps_enabled){ return true; } else if(counts <= 4){ return false; } if(sat_count < min_gps_sat_count){ //if 20-25 sec and 3 satellites found then stop if(counts >= 40 && sat_count >= 3){ return true; } return false; } } return true; } /** * Best location abstract result class */ public static abstract class LocationResult{ public abstract void gotLocation(Location location); } /** * Initialize starting values and starting best location listeners * * @param Context ctx * @param LocationResult result */ public void init(Context ctx, LocationResult result){ context = ctx; locationResult = result; myLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); gps_enabled = (Boolean) myLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); bestLocation = null; counts = 0; // turning on location updates myLocationManager.requestLocationUpdates("network", 0, 0, networkLocationListener); myLocationManager.requestLocationUpdates("gps", 0, 0, gpsLocationListener); myLocationManager.addGpsStatusListener(gpsStatusListener); // starting best location finder loop handler.postDelayed(showTime, iteration_timeout_step); } /** * GpsStatus listener. OnChainged counts connected satellites count. */ public final GpsStatus.Listener gpsStatusListener = new GpsStatus.Listener() { public void onGpsStatusChanged(int event) { if(event == GpsStatus.GPS_EVENT_SATELLITE_STATUS){ try { // Check number of satellites in list to determine fix state GpsStatus status = myLocationManager.getGpsStatus(null); Iterable<GpsSatellite>satellites = status.getSatellites(); sat_count = 0; Iterator<GpsSatellite>satI = satellites.iterator(); while(satI.hasNext()) { GpsSatellite satellite = satI.next(); System.println("Satellite: snr=" + satellite.getSnr() + ", elevation=" + satellite.getElevation()); sat_count++; } } catch (Exception e) { e.printStackTrace(); sat_count = min_gps_sat_count + 1; } System.println("#### sat_count = " + sat_count); } } }; /** * Gps location listener. */ public final LocationListener gpsLocationListener = new LocationListener(){ @Override public void onLocationChanged(Location location){ } public void onProviderDisabled(String provider){} public void onProviderEnabled(String provider){} public void onStatusChanged(String provider, int status, Bundle extras){} }; /** * Network location listener. */ public final LocationListener networkLocationListener = new LocationListener(){ @Override public void onLocationChanged(Location location){ } public void onProviderDisabled(String provider){} public void onProviderEnabled(String provider){} public void onStatusChanged(String provider, int status, Bundle extras){} }; /** * Returns best location using LocationManager.getBestProvider() * * @param context * @return Location|null */ public static Location getLocation(Context context){ System.println("getLocation()"); // fetch last known location and update it try { LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); String strLocationProvider = lm.getBestProvider(criteria, true); System.println("strLocationProvider=" + strLocationProvider); Location location = lm.getLastKnownLocation(strLocationProvider); if(location != null){ return location; } return null; } catch (Exception e) { e.printStackTrace(); return null; } }}
min_gps_sat_count
如果启用GPS,此课程将尝试连接到卫星。否则返回LocationManager.getBestProvider()
位置。检查代码!
添加回答
举报
0/150
提交
取消