0

返回我有以下邏輯:谷歌Android地方的照片搜索API不工作PlaceId從地方搜索Web服務API

服務器端進行Place Search Web服務調用,並得到有效的獨特的跨谷歌地圖API的PlaceId字符串。檢查:從他手中構建Place Details的手動URL(返回PlaceId)會返回預期的Place,表示他在Google的位置DB中有照片(結果中的photos[] Json不爲空...)。

所以現在服務器發送到Android客戶端這個PlaceId和在Android我做API調用Places Photos得到至少一個圖像。它應該可以工作,因爲PlaceId是所有Google地圖產品中唯一的地點標識符。基於官方的Google示例,工作流程非常簡單直接,如代碼中的註釋所示,連接部分成功並且所有API設置都很好(在開發控制檯中,清單中有API KEY等)。

問題是它不工作:在dev控制檯中,我看到使用次數增加,並且在代碼中我希望獲取圖像的地方沒有任何反應 - 結果是我嘗試了任何PlaceId(並且如上所述應該有照片)在Google的數據庫中沒有任何照片。也不是例外或類似的東西來調試。哪裏有問題?謝謝,

//Under Activity extends FragmentActivity implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks 

private GoogleApiClient mGoogleApiClient = null; 
private boolean isConnected = false; 
private ImageView mImageView; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    /* Regular code... */ 
    //Next 2 lines: I don't for what they are good - But in the official Google sample 
    //they appears - So probably it's right... 
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
    StrictMode.setThreadPolicy(policy); 
    if (mGoogleApiClient == null) { 
     rebuildGoogleApiClient(); 
    } 
    if (isConnected) { 
     /* This is printed! */ 
     Log.e("TAG", "Start of API Call"); 
     String placeId = /* Call to my server, the result is 100% valid PlaceId that has photos*/ 
     placePhotosTask(placeId, 800, 400); //Height, Width 
    } 
} 

private void placePhotosTask(final String placeId, final int width, final int height) { 
    new PhotoTask(width, height) { 
     @Override 
     protected void onPreExecute() { 
      //TODO Display a temporary image to show while bitmap is loading. 
      //mImageView.setImageResource(R.drawable.empty_photo); 
     } 

     @Override 
     protected void onPostExecute(AttributedPhoto attributedPhoto) { 
      if (attributedPhoto != null) { 
       /* THIS IS NOT PRINTED */ 
       Log.e("TAG", "Success of API Call"); 
       mImageView.setImageBitmap(attributedPhoto.bitmap); 
      } 
     } 
    }.execute(placeId); 
} 

private class PhotoTask extends AsyncTask<String, Void, PhotoTask.AttributedPhoto> { 

    private int mHeight; 
    private int mWidth; 

    public PhotoTask(int width, int height) { 
     mHeight = height; 
     mWidth = width; 
    } 

    //Loads the first photo for a place id from the Geo Data API. The place id must be the first (and only) parameter. 
    @Override 
    protected AttributedPhoto doInBackground(String... params) { 
     if (params.length != 1) { 
      return null; 
     } 
     final String placeId = params[0]; 
     AttributedPhoto attributedPhoto = null; 
     PlacePhotoMetadataResult result = Places.GeoDataApi.getPlacePhotos(mGoogleApiClient, placeId).await(); 
     if (result.getStatus().isSuccess()) { 
      PlacePhotoMetadataBuffer photoMetadataBuffer = result.getPhotoMetadata(); 
      //BUG!: photoMetadataBuffer.getCount() == 0 Always! 
      if (photoMetadataBuffer.getCount() > 0 && !isCancelled()) { 
       //Get the first bitmap and its attributions. 
       PlacePhotoMetadata photo = photoMetadataBuffer.get(0); 
       CharSequence attribution = photo.getAttributions(); 
       //Load a scaled bitmap for this photo. 
       Bitmap image = photo.getScaledPhoto(mGoogleApiClient, mWidth, mHeight).await().getBitmap(); 
       attributedPhoto = new AttributedPhoto(attribution, image); 
      } 
      //Release the PlacePhotoMetadataBuffer. 
      photoMetadataBuffer.release(); 
     } 
     return attributedPhoto; 
    } 

    //Holder for an image and its attribution. 
    class AttributedPhoto { 
     public final CharSequence attribution; 
     public final Bitmap bitmap; 
     public AttributedPhoto(CharSequence attribution, Bitmap bitmap) { 
      this.attribution = attribution; 
      this.bitmap = bitmap; 
     } 
    } 

} 

protected synchronized void rebuildGoogleApiClient() { 
    mGoogleApiClient = new GoogleApiClient.Builder(this) 
     .enableAutoManage(this, 0 /* clientId */, this) 
     .addConnectionCallbacks(this) 
     .addApi(Places.GEO_DATA_API) 
     .build(); 
} 

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    isConnected = false; 
} 

@Override 
public void onConnected(Bundle bundle) { 
    isConnected = true; 
} 

@Override 
public void onConnectionSuspended(int i) { 
    isConnected = false; 
} 
+0

它是否僅適用於特定的PlaceID或所有的PlaceID? – Brett

回答

2

我不同意bug評論 - photoMetadataBuffer.getCount() == 0 Always。這裏是一些代碼,顯示成功加載照片。請注意,對於上下文,此代碼是在Android Studio Google地圖模板應用程序內部構建的,以便更容易地將所有API密鑰配置正確插入到應用程序中,並帶有用於顯示結果的地圖。

private GoogleMap mMap; 
private GoogleApiClient mGoogleApiClient; 
private final String placeId = "ChIJhSxoJzyuEmsR9gBDBR09ZrE"; 
private final static String TAG = "MapsActivity"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_maps); 
    // Obtain the SupportMapFragment and get notified when the map is ready to be used. 
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
      .findFragmentById(R.id.map); 
    mapFragment.getMapAsync(this); 

    mGoogleApiClient = new GoogleApiClient 
      .Builder(this) 
      .addApi(Places.GEO_DATA_API) 
      .addApi(Places.PLACE_DETECTION_API) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .build(); 
} 

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

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

@Override 
public void onMapReady(GoogleMap googleMap) { 
    mMap = googleMap; 

    Places.GeoDataApi.getPlaceById(mGoogleApiClient, placeId).setResultCallback(new ResultCallback<PlaceBuffer>() { 
     @Override 
     public void onResult(PlaceBuffer places) { 
      if (places.getStatus().isSuccess() && places.getCount() > 0) { 
        final Place myPlace = places.get(0); 
        Log.i(TAG, "Place found: " + myPlace.getName()); 
        mMap.addMarker(new MarkerOptions() 
          .position(myPlace.getLatLng()) 
          .title(myPlace.getName().toString()) 
          .snippet(myPlace.getAddress().toString())); 
        mMap.moveCamera(CameraUpdateFactory.newLatLng(myPlace.getLatLng())); 
      } 
      places.release(); 
     } 
    }); 

    Places.GeoDataApi.getPlacePhotos(mGoogleApiClient, placeId).setResultCallback(new ResultCallback<PlacePhotoMetadataResult>() { 
     @Override 
     public void onResult(PlacePhotoMetadataResult placePhotoMetadataResult) { 
      if (placePhotoMetadataResult.getStatus().isSuccess()) { 
       PlacePhotoMetadataBuffer photoMetadata = placePhotoMetadataResult.getPhotoMetadata(); 
       int photoCount = photoMetadata.getCount(); 
       for (int i = 0; i<photoCount; i++) { 
        PlacePhotoMetadata placePhotoMetadata = photoMetadata.get(i); 
        final String photoDetail = placePhotoMetadata.toString(); 
        placePhotoMetadata.getScaledPhoto(mGoogleApiClient, 500, 500).setResultCallback(new ResultCallback<PlacePhotoResult>() { 
         @Override 
         public void onResult(PlacePhotoResult placePhotoResult) { 
          if (placePhotoResult.getStatus().isSuccess()) { 
           Log.i(TAG, "Photo "+photoDetail+" loaded"); 
          } else { 
           Log.e(TAG, "Photo "+photoDetail+" failed to load"); 
          } 
         } 
        }); 
       } 
       photoMetadata.release(); 
      } else { 
       Log.e(TAG, "No photos returned"); 
      } 
     } 
    }); 
} 
+0

好的發現了這個錯誤。問題是服務器將地點id作爲帶引號的字符串返回。無論如何,在我的方法中,我使用了'Places.GeoDataApi.getPlacePhotos(mGoogleApiClient,placeId).await();'。匿名結果回調的實現更好。 – michael

+0

是的,如果從UI線程調用,則在android上使用await()會很糟糕。回調更好。謝謝! – Brett

+0

謝謝!我可以加載bitImage到我的圖像。 –