Android一次findGPS位置,显示加载对话框

我正在编写一个需要用户当前位置的应用程序(lastknownlocation不会很有帮助),并显示从数据库中获取的所有最接近“项目”的列表。

我已经find了最接近项目的工作,但是目前只使用硬编码的经纬度位置,但是现在是时候实施查找实际位置了。

任何人都可以提供如何让应用程序在后台find当前好的位置,并让应用程序等待的例子。 我只需要位置一旦没有更新随着人的移动。 我已经实现了一个位置监听器,但我知道得到一个GPS修复可能会很慢。 我已经看到了其他例子使用最后一个已知的位置或实现位置监听器继续运行和更新,但我的活动需要的位置坐标之前,它可以显示任何应用程序崩溃。 我需要在search时显示一个进度对话框。

如何让locationlistener在后台运行一次,然后在find位置后删除位置更新。 我需要其他的应用程序等待,直到它有一个GPS位置或20-30秒后超时。 我想要一个ProgressDialog,所以用户知道事情正在进行,但它只是旋转加载animation不是百分比或任何东西。 如果可能的话,我希望用户能够取消对话,如果他们厌倦了等待,然后他们可以通过input郊区等search。

我一直在尝试用线程来做,但是它变得比我觉得应该更复杂,仍然不能工作。 在iPhone上这是更简单?

任何人都可以提供一个很好的方式来做到这一点,我已经把我的头发一个星期,这是真的让我落后于应用程序完成date的其余部分。

总之我想:
*find当前的坐标
*获取位置时显示进度对话框
*有应用程序能够等待成功的位置或一段时间后放弃吗?
*如果成功:closures进度对话框,并使用坐标来运行我的其他方法查找项目closeby。
*如果获取位置失败:closures进度对话框并显示错误消息,并鼓励用户使用菜单转到search活动。
*如果用户从菜单中select地图视图,则使用这些坐标来显示地图上的当前位置,并使用数据库中的坐标在所有附近项目上放置针脚。

谢谢你们,我希望我已经解释得很清楚了。 任何问题只是问,我会定期检查,因为我热衷于完成这个部分。 干杯

编辑
代码按要求

locationList活动文件

protected void onStart() { super.onStart(); // .... new LocationControl().execute(this); } private class LocationControl extends AsyncTask<Context, Void, Void> { private final ProgressDialog dialog = new ProgressDialog(branchAtmList.this); protected void onPreExecute() { this.dialog.setMessage("Determining your location..."); this.dialog.show(); } protected Void doInBackground(Context... params) { LocationHelper location = new LocationHelper(); location.getLocation(params[0], locationResult); return null; } protected void onPostExecute(final Void unused) { if(this.dialog.isShowing()) { this.dialog.dismiss(); } useLocation(); //does the stuff that requires current location } } public LocationResult locationResult = new LocationResult() { @Override public void gotLocation(final Location location) { currentLocation = location; } }; 

LocationHelper类

  package org.xxx.xxx.utils; import java.util.Timer; /* imports */ public class LocationHelper { LocationManager locationManager; private LocationResult locationResult; boolean gpsEnabled = false; boolean networkEnabled = false; public boolean getLocation(Context context, LocationResult result) { locationResult = result; if(locationManager == null) { locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); } //exceptions thrown if provider not enabled try { gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); } catch (Exception ex) {} try { networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); } catch (Exception ex) {} //dont start listeners if no provider is enabled if(!gpsEnabled && !networkEnabled) { return false; } if(gpsEnabled) { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps); } if(networkEnabled) { locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork); } GetLastLocation(); return true; } LocationListener locationListenerGps = new LocationListener() { public void onLocationChanged(Location location) { locationResult.gotLocation(location); locationManager.removeUpdates(this); locationManager.removeUpdates(locationListenerNetwork); } public void onProviderDisabled(String provider) {} public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extra) {} }; LocationListener locationListenerNetwork = new LocationListener() { public void onLocationChanged(Location location) { locationResult.gotLocation(location); locationManager.removeUpdates(this); locationManager.removeUpdates(locationListenerGps); } public void onProviderDisabled(String provider) {} public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extra) {} }; private void GetLastLocation() { locationManager.removeUpdates(locationListenerGps); locationManager.removeUpdates(locationListenerNetwork); Location gpsLocation = null; Location networkLocation = null; if(gpsEnabled) { gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); } if(networkEnabled) { networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } //if there are both values use the latest one if(gpsLocation != null && networkLocation != null) { if(gpsLocation.getTime() > networkLocation.getTime()) { locationResult.gotLocation(gpsLocation); } else { locationResult.gotLocation(networkLocation); } return; } if(gpsLocation != null) { locationResult.gotLocation(gpsLocation); return; } if(networkLocation != null) { locationResult.gotLocation(networkLocation); return; } locationResult.gotLocation(null); } public static abstract class LocationResult { public abstract void gotLocation(Location location); } } 

这看起来像是一个很大的努力,只是为了获得当前位置一次? 我不需要更新或任何东西? 有没有更简单的方法让应用程序等待结果? 我一直坚持这么久。

Solutions Collecting From Web of "Android一次findGPS位置,显示加载对话框"

使用AsyncTask并使用network_provider以及gps_provider ,这意味着两个侦听器。 GPS需要更长时间才能得到修复,有时候可能只有一分钟,只能在户外工作,而networking的位置相当快。

一个很好的代码示例是: 在Android上获取用户当前位置的最简单和最健壮的方法是什么?

对于AsyncTask,请看http://developer.android.com/reference/android/os/AsyncTask.html

在这里也有很多代码示例,例如: Android显示一个对话框,直到线程完成,然后继续执行程序

编辑:代码概念:

添加类variables

 boolean hasLocation = false; 

调用onCreate(不在AsyncTask中):

 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 

然后在locationListener.onLocationChanged中,find一个位置后更改值:

 boolean hasLocation = false; 

AsyncTask:保持原样,但不要调用

 LocationHelper location = new LocationHelper(); location.getLocation(params[0], locationResult); 

在那里,而不是

 Long t = Calendar.getInstance().getTimeInMillies(); while (!hasLocation && Calendar.getInstance().getTimeInMillies()-t<30000)) { Thread.Sleep(1000); }; 

大概在两者之间延迟就足够了。

我仍然不喜欢这是如何工作的,而且似乎比它应该更为复杂,但是直到有人提供了一种更好的方式,我现在就开始工作了。

如果有人遇到这一点,并build议一个更好的清洁结果,只获得用户的当前位置坐标只是一次,然后停止看,将不胜感激!

 private LocationControl locationControlTask; private boolean hasLocation = false; LocationHelper locHelper; 

从onCreate()我打电话

 locHelper = new LocationHelper(); locHelper.getLocation(context, locationResult); locationControlTask = new LocationControl(); locationControlTask.execute(this); 

然后我有一个私人类LocationControl

 private class LocationControl extends AsyncTask<Context, Void, Void> { private final ProgressDialog dialog = new ProgressDialog(activityname.this); protected void onPreExecute() { this.dialog.setMessage("Searching"); this.dialog.show(); } protected Void doInBackground(Context... params) { //Wait 10 seconds to see if we can get a location from either network or GPS, otherwise stop Long t = Calendar.getInstance().getTimeInMillis(); while (!hasLocation && Calendar.getInstance().getTimeInMillis() - t < 15000) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }; return null; } protected void onPostExecute(final Void unused) { if(this.dialog.isShowing()) { this.dialog.dismiss(); } if (currentLocation != null) { useLocation(); } else { //Couldn't find location, do something like show an alert dialog } } } 

然后一个locationResult ..

 public LocationResult locationResult = new LocationResult() { @Override public void gotLocation(final Location location) { currentLocation = new Location(location); hasLocation = true; } }; 

此外,为了避免你像我这样年龄的头发拉出你的头发记得要停止位置控制任务,如果有人离开活动提前,也停止位置更新停止运行GPS时,用户离开。 在onStop()做这样的事情:

 locHelper.stopLocationUpdates(); locationControlTask.cancel(true); 

此外,Location Helper类中的stopLocationUpdates也执行以下操作:

 public void stopLocationUpdates() { locationManager.removeUpdates(locationListenerGps); locationManager.removeUpdates(locationListenerNetwork); } 

祝你好运,我需要它…

为什么不创build一个AsyncTask为什么你不创build一个ProgressDialog框并closurespublic void gotLocation(final Location location){} ? 您还可以将onCancelListener添加到ProgressDialog框并取消当前的任何位置请求。