2011-05-20 40 views
1

我有一個應用程序,它使用GPS或網絡信號找到用戶的位置(加載進度對話框中),當它發現它的位置時,座標被寫入文本視圖。如果GPS在40秒內未找到位置,或者用戶單擊取消按鈕,則對話框關閉。問題是,如果我點擊取消對話框,它不會消除。但是,如果我再次點擊,它會被解僱。爲什麼我必須點擊兩次?!?下面是源代碼:GPS定位一次

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> 

和在清單

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

我希望這2個權限如果有人會看看在錯誤。

+0

請縮進您的代碼,並將xml部分標記爲代碼,這樣問題就會變得可讀。 – MByD 2011-05-20 20:06:50

回答

1

我沒有對您的代碼進行深入分析,但是您正在onCreate和onStart中啓動aysnc任務。從其中一箇中刪除它,因爲我懷疑你只是在另一個對話框上有一個對話框。

+2

謝謝,你我是對的,我打開對話框兩次。我從onCreate()中刪除它,但這是否意味着,每當應用程序進入後臺或暫停,並在一段時間後,如果用戶再次返回到應用程序,然後onStart()被調用,或者我應該實現onResume? – 2011-05-21 07:30:23

+0

我不確定爲什麼你的對話存在,所以回答這個問題有點難。如果在活動結束前顯示對話框(並且活動未被終止),那麼當您返回時(無需執行任何操作),它仍應顯示。如果活動被殺死,那麼你有開放代碼的任何功能將再次顯示(創建,啓動或恢復)。訣竅在於確保對話不會在需要您的活動實例被終止的情況之後重新顯示(如果用戶在離開您的應用之前關閉了它)。 – 2011-05-23 18:53:47