GPS定位一次
我有一个应用程序,它使用 GPS 或网络信号查找用户位置(在进度对话框中加载),当它找到位置时,坐标会写入文本视图中。如果 GPS 在 40 秒内未找到位置或用户单击取消按钮 ,则对话框将关闭。问题是,如果我单击取消对话框,它不会关闭。但是,如果我再次点击,它就会消失。为什么我必须点击两次?!?下面是源代码:
public class MainActivity extends Activity {
private LocationControl locationControlTask;
private boolean hasLocation = false;
LocationHelper locHelper;
protected Location currentLocation;
private TextView myText;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myText = (TextView)findViewById(R.id.mytext);
locHelper = new LocationHelper();
locHelper.getLocation(MainActivity.this, locationResult);
locationControlTask = new LocationControl();
locationControlTask.execute(this);
}
protected void onStart()
{
super.onStart();
// ....
new LocationControl().execute(this);
}
private class LocationControl extends AsyncTask<Context, Void, Void>
{
private final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
protected void onPreExecute()
{
this.dialog.setMessage("Tap to cancel");
this.dialog.setTitle("Searching");
this.dialog.setCancelable(true);
this.dialog.setButton(Dialog.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(which == Dialog.BUTTON_NEGATIVE) {
dialog.dismiss();
Toast.makeText(MainActivity.this, "dialog canceled", Toast.LENGTH_SHORT).show();
}
}
});
this.dialog.show();
}
protected Void doInBackground(Context... params)
{
//Wait 40 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 < 40000) {
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();
String text = "lat:"+currentLocation.getLatitude()+" long:"+currentLocation.getLongitude();
myText.setText(text);
}
else
{
Toast.makeText(MainActivity.this, "location could not be found", Toast.LENGTH_SHORT).show();
//Couldn't find location, do something like show an alert dialog
}
}
}
public LocationResult locationResult = new LocationResult()
{
@Override
public void gotLocation(final Location location)
{
currentLocation = new Location(location);
hasLocation = true;
}
};
@Override
protected void onStop() {
locHelper.stopLocationUpdates();
locationControlTask.cancel(true);
super.onStop();
}
}
位置助手:
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)
{ //if()
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 void stopLocationUpdates() {
locationManager.removeUpdates(locationListenerGps);
locationManager.removeUpdates(locationListenerNetwork);
}
public static abstract class LocationResult
{
public abstract void gotLocation(Location location);
}
}
xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/mytext"
android:textSize="15dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Main activity"/>
</LinearLayout>
以及清单中的这 2 个权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
如果有人愿意查看该错误,我将不胜感激。
I have an app that finds the users location (loading in a progress dialog) using GPS or network signal , when it finds it's location, the coordinates are written in a text view . If the GPS doesn't find a location in 40 sec or the user clicks on the cancel button , then the dialog closes. The problem is that if I click to cancel the dialog , it doesn't dismiss. However, if I click again, it dismisses. Why do I have to click twice ?!? Below is the source code:
public class MainActivity extends Activity {
private LocationControl locationControlTask;
private boolean hasLocation = false;
LocationHelper locHelper;
protected Location currentLocation;
private TextView myText;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myText = (TextView)findViewById(R.id.mytext);
locHelper = new LocationHelper();
locHelper.getLocation(MainActivity.this, locationResult);
locationControlTask = new LocationControl();
locationControlTask.execute(this);
}
protected void onStart()
{
super.onStart();
// ....
new LocationControl().execute(this);
}
private class LocationControl extends AsyncTask<Context, Void, Void>
{
private final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
protected void onPreExecute()
{
this.dialog.setMessage("Tap to cancel");
this.dialog.setTitle("Searching");
this.dialog.setCancelable(true);
this.dialog.setButton(Dialog.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(which == Dialog.BUTTON_NEGATIVE) {
dialog.dismiss();
Toast.makeText(MainActivity.this, "dialog canceled", Toast.LENGTH_SHORT).show();
}
}
});
this.dialog.show();
}
protected Void doInBackground(Context... params)
{
//Wait 40 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 < 40000) {
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();
String text = "lat:"+currentLocation.getLatitude()+" long:"+currentLocation.getLongitude();
myText.setText(text);
}
else
{
Toast.makeText(MainActivity.this, "location could not be found", Toast.LENGTH_SHORT).show();
//Couldn't find location, do something like show an alert dialog
}
}
}
public LocationResult locationResult = new LocationResult()
{
@Override
public void gotLocation(final Location location)
{
currentLocation = new Location(location);
hasLocation = true;
}
};
@Override
protected void onStop() {
locHelper.stopLocationUpdates();
locationControlTask.cancel(true);
super.onStop();
}
}
The location helper:
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)
{ //if()
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 void stopLocationUpdates() {
locationManager.removeUpdates(locationListenerGps);
locationManager.removeUpdates(locationListenerNetwork);
}
public static abstract class LocationResult
{
public abstract void gotLocation(Location location);
}
}
the xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/mytext"
android:textSize="15dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Main activity"/>
</LinearLayout>
and these 2 permissions in manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
I would appreciate it if anyone would take a look at the bug.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我没有对您的代码进行深入分析,但您正在 onCreate 和 onStart 中启动 aysnc 任务。将其从其中之一中删除,因为我怀疑您只是将一个对话框放在另一个对话框之上。
I didn't do an in-depth analysis of your code, but you are starting the aysnc task in both onCreate and onStart. Remove it from one of those, because I suspect you simply have one dialog on top of the other.