0

我需要應用啓動時的位置。我跟隨這個tut withlocallocationapi得到LastLocation:https://developer.android.com/training/location/retrieve-current.html在應用啓動時獲取位置地址

當查詢地址的AsyncTask通過一個按鈕執行,但當我把相同的片段放在oncreate或onstart,然後獲得NPE,它可能是完美的定位修復需要很長時間。

我想要加載活動,顯示ProgressBar &然後顯示位置,而不必點擊按鈕。

解決方法是在onstart短暫延遲後執行AsyncTask,但我猜測應該有更高效的東西。

public class MainActivity extends ActionBarActivity implements 
    ConnectionCallbacks, OnConnectionFailedListener{ 


protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    mAddress = (TextView) findViewById(R.id.address); 
    mActivityIndicator = 
      (ProgressBar) findViewById(R.id.address_progress); 

    buildGoogleApiClient(); 
} 

protected synchronized void buildGoogleApiClient() { 
    mGoogleApiClient = new GoogleApiClient.Builder(this) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .addApi(LocationServices.API) 
      .build(); 
} 


@Override 
protected void onStart() { 
    super.onStart(); 
    mGoogleApiClient.connect(); 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
    if (mGoogleApiClient.isConnected()) { 
     mGoogleApiClient.disconnect(); 
    } 
} 

public void onConnected(Bundle connectionHint) { 
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
} 

private class GetAddressTask extends AsyncTask<Location, Void, String> 
{ 
    Context mContext; 
    public GetAddressTask(Context context) { 
     super(); 
     mContext = context; 
    } 
    @Override 
    protected String doInBackground(Location... params) { 
     Geocoder geocoder = 
       new Geocoder(mContext, Locale.getDefault()); 
     // Get the current location from the input parameter list 
     Location loc = params[0]; 
     // Create a list to contain the result address 
     List<Address> addresses = null; 
     try { 
      addresses = geocoder.getFromLocation(loc.getLatitude(), 
        loc.getLongitude(), 1); 
     } catch (IOException e1) { 
      Log.e("LocationSampleActivity", 
        "IO Exception in getFromLocation()"); 
      e1.printStackTrace(); 
      return ("IO Exception trying to get address"); 
     } catch (IllegalArgumentException e2) { 
      // Error message to post in the log 
      String errorString = "Illegal arguments " + 
        Double.toString(loc.getLatitude()) + 
        " , " + 
        Double.toString(loc.getLongitude()) + 
        " passed to address service"; 
      Log.e("LocationSampleActivity", errorString); 
      e2.printStackTrace(); 
      return errorString; 
     } 
     // If the reverse geocode returned an address 
     if (addresses != null && addresses.size() > 0) { 
      // Get the first address 
      Address address = addresses.get(0); 
      /* 
      * Format the first line of address (if available), 
      * city, and country name. 
      */ 
      String addressText = String.format(
        "%s, %s, %s", 
        // If there's a street address, add it 
        address.getMaxAddressLineIndex() > 0 ? 
          address.getAddressLine(0) : "", 
        // Locality is usually a city 
        address.getLocality(), 
        // The country of the address 
        address.getCountryName()); 
      // Return the text 
      return addressText; 
     } else { 
      return "No address found"; 
     } 
    } 

    @Override 
    protected void onPostExecute(String address) { 
     // Set activity indicator visibility to "gone" 
     mActivityIndicator.setVisibility(View.GONE); 
     // Display the results of the lookup. 
     mAddress.setText(address); 
    } 
} 

public void getAddress(View v) { 
    // Ensure that a Geocoder services is available 
    if (Build.VERSION.SDK_INT >= 
      Build.VERSION_CODES.GINGERBREAD 
      && 
      Geocoder.isPresent()) { 
     // Show the activity indicator 
     mActivityIndicator.setVisibility(View.VISIBLE); 
     /* 
     * Reverse geocoding is long-running and synchronous. 
     * Run it on a background thread. 
     * Pass the current location to the background task. 
     * When the task finishes, 
     * onPostExecute() displays the address. 
     */ 
     (new GetAddressTask(this)).execute(mLastLocation); 
    } 
} 
+0

第一:請檢查空在doInBackground。您獲得最後位置的電話並不能保證它始終返回值。儘管如此,這不是一個好的做法。考慮在onConmected()中創建LocationRequest,並請求位置回調/偵聽器,並在onLocationChanged(Location loc)中獲取您的位置/運行getAddress方法。關於實施情況,請立即通知Google –

回答

1

除非GoogleApiClient處於連接狀態,否則API調用將失敗。您請求它在onStart中連接並且它是異步連接的。你顯然不應該在onStart中放置一個隨機延遲,而且你不應該在AsyncTask中這樣做,因爲這將是片狀的。

在發生onConnected回調時(或之後)發起您的API調用。也許使用條件邏輯,這樣如果您的應用程序恢復,則不會再次進行呼叫。

0

既然這是一個直接的答案,我會在這裏發表。

簡而言之:請看看我的要點

https://gist.github.com/2022a4d2c21d73f042eb

釋:

GoogleApiClient成功連接到谷歌的服務後,它不能獲得一眨不眨的完整信息,您應該意識到這一點。所以基本上,您會希望向您要使用的API(FuseLocation API,Google Fit API ...)發出請求。而onConnected()方法是您開始請求的地方。 GoogleAPIClient爲您提供的每個API都將以自己的方式實現回調,您也應該查看文檔。所以請考慮看看我的要點,並提供反饋,如果它的工作。

0

執行下列操作(順便說一句,我試圖以正確的格式輸入代碼,但它不會採取很抱歉,如果下面看起來邋遢):

  1. 在的onCreate,請設置您GoogleApiClient :

    mGoogleApiClient = new GoogleApiClient.Builder(this) 
         .addConnectionCallbacks(this) 
         .addOnConnectionFailedListener(this) 
         .addApi(LocationServices.API) 
         .build(); 
    
    mLocationRequest = LocationRequest.create() 
         .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
         .setInterval(10000).setFastestInterval(5000); 
    
  2. 處理通信/的onResume,連接到您的GoogleApiClient:

    mGoogleApiClient.connect();

  3. 在的onPause,從GoogleApiClient斷開:

    if (mGoogleApiClient.isConnected()) { 
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
        mGoogleApiClient.disconnect(); 
    } 
    
  4. 在的onConnect回調方法,執行以下操作:

    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,FragmentPostActivity。這個);

  5. 在onLocationChanged,讓你的位置,然後斷開:

    公共無效onLocationChanged(位置定位){

    mLastLocation = location; 
    if (mGoogleApiClient.isConnected() && mLastLocation != null) { 
        Log.e("LocationChanged", String.valueOf(location.getLatitude()) + " Longitude: " + String.valueOf(location.getLongitude())); 
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
        mGoogleApiClient.disconnect(); 
    } 
    

    }