【问题标题】:Android Google Places Photos Search API not working on PlaceId returned from Place Search web service APIAndroid Google Places Photos Search API 无法处理从 Place Search Web 服务 API 返回的 PlaceId
【发布时间】:2015-10-14 19:27:01
【问题描述】:

我有以下逻辑:

服务器端调用Place Search 网络服务并获取有效的唯一跨Google 地图API 的PlaceId 字符串。检查:从他那里手动构造Place Details 的URL(返回PlaceId)返回预期的Place,表明他在Google 的地点数据库中有照片(photos[] 在结果Json 中不为空...)。

所以现在服务器将这个PlaceId 发送给Android 客户端,在Android 中我对Places Photos 进行API 调用以获取至少一张图像。它应该可以工作,因为PlaceId 是所有谷歌地图产品的唯一地点标识符。工作流程基于 Google 官方示例非常简单,如代码中的 cmets 所示,连接部分成功并且所有 API 设置都很好(在开发控制台中,清单带有 API KEY 等)。

问题在于它不起作用:在开发控制台中,我看到使用次数增加,并且在我希望获取图像的代码中没有任何反应 - 结果是我尝试的任何 PlaceId(如前所述上面应该有照片)在谷歌的数据库中没有任何照片。也不是要调试的异常或类似的东西。问题出在哪里?谢谢,

//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;
}

【问题讨论】:

  • 是只发生在特定的PlaceIDs,还是所有PlaceIDs?

标签: android google-maps google-maps-api-3 google-places-api android-googleapiclient


【解决方案1】:

我不同意错误评论 - photoMetadataBuffer.getCount() == 0 Always。这是一些显示成功加载照片的代码。请注意,就上下文而言,此代码是在 Android Studio Google Maps 模板应用程序中构建的,以便更轻松地将所有 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");
            }
        }
    });
}

【讨论】:

  • 好的,发现了这个错误。问题是服务器将地点 id 作为带引号的字符串返回。无论如何,在我的方法中,我使用了Places.GeoDataApi.getPlacePhotos(mGoogleApiClient, placeId).await();。您的匿名结果回调实现更好。
  • 是的,如果从 UI 线程调用,在 android 上使用 await() 会很糟糕。回调更好。谢谢!
  • 谢谢!!我可以将 bitImage 加载到我的图像中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多