由于公司项目是针对美国市场,所以接入的是google定位
谷歌地图sdk不像高德地图或者百度地图那么好接入,一方面是纯英文,还有一方面国外文档习惯我们并不习惯,大多写得很简略
我的项目要实现附近宠物店的搜索和附近宠物医院的搜索,在接入谷歌地图用到了以下几个包:
"com.google.android.gms:play-services-maps:15.0.1"
"com.google.android.gms:play-services-location:15.0.1"
"com.google.android.gms:play-services-places:15.0.1"
此外还需要在清单文件中配置对应的
注:在string.xml中的谷歌地图的key的名字必须是google_maps_key
下面实现的搜索的功能:本质上调用的http接口来实现,比较坑的一点是同一个key一天调用的次数最多150000次,如果用户量较大时,要专门交费调整限制次数
1.首先初始化
private GoogleApiClient mGoogleApiClient;
private void getLocationList() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
return;
}
//创建GoogleAPIClient实例
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
2.调用接口进行请求地址数据:
private void getGoogleLocation() {
String baseUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=";
// String realUrl=baseUrl+mLat+","+mLng+"&radius="
// +5000+"&type=pet_store"+"&language=zh-CN"+"&key="+"你自己在谷歌的对应的key";
String realUrl = null;
// realUrl = baseUrl + mLat + "," + mLng + "&radius="
// + 20000 +"&rankby=distance"+
// "&types=" + searchType + "&key=" + "你自己在谷歌的对应的key";
realUrl = baseUrl + mLat + "," + mLng +"&rankby=distance"+
"&types=" + searchType + "&key=" + "你自己在谷歌对应的key";
Call ca = HBClient.getService(MineService.class).listGoogleLocations(realUrl);
ca.enqueue(new RequestCallBack() {
@Override
public void onFailed(Call call, Response response) {
super.onFailed(call, response);
}
@Override
public void onFailure(Call call, Throwable t) {
super.onFailure(call, t);
}
@Override
public void onSuccess(Call call, Response response) {
try {
String json = response.body().string();
LogUtil.e("周边地址的json为" + json);
if (json != null && !json.equals("")) {
googleLocationBean = GsonUtils.jsonToBean(json, GoogleLocationBean.class);
if (googleLocationBean == null) {
LogUtil.e("解析周边地址json为空");
showEmpty();
nextPageToken = null;
} else {
if (googleLocationBean.getStatus().equals("OK")) {
List results = googleLocationBean.getResults();
nextPageToken = googleLocationBean.getNext_page_token();
showSuccess();
mAdapter.setNewData(results);
LogUtil.e("长度为" + results.size());
// for (int i = 0; i < results.size(); i++) {
// getGoogleDetail(results.get(i),results,i,hasMore);
// }
// getGooglePhotos(results.get(1).getReference());
} else {
nextPageToken = null;
showEmpty();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
3.当请求返回的数据中有
nextPageToken字段不为空时,就有多页数据,请求下一页数据时需要将该字段携带去请求
4.请求下一页数据时:
private void getGoogleLocationMore() {
String baseUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?pagetoken=";
String realUrl = null;
realUrl = baseUrl + nextPageToken + "&key=" + "你对应的谷歌的key";
nextPageToken = null;
Call ca = HBClient.getService(MineService.class).listGoogleLocations(realUrl);
ca.enqueue(new RequestCallBack() {
@Override
public void onFailed(Call call, Response response) {
super.onFailed(call, response);
}
@Override
public void onFailure(Call call, Throwable t) {
super.onFailure(call, t);
}
@Override
public void onSuccess(Call call, Response response) {
try {
String json = response.body().string();
LogUtil.e("周边地址的json为" + json);
if (json != null && !json.equals("")) {
googleLocationBean = GsonUtils.jsonToBean(json, GoogleLocationBean.class);
if (googleLocationBean == null) {
LogUtil.e("解析周边地址json为空");
mAdapter.loadMoreEnd();
nextPageToken = null;
} else {
if (googleLocationBean.getStatus().equals("OK")) {
List results = googleLocationBean.getResults();
mAdapter.addData(results);
mAdapter.loadMoreEnd();
nextPageToken = googleLocationBean.getNext_page_token();
LogUtil.e("长度为" + results.size());
// for (int i = 0; i < results.size(); i++) {
// getGoogleDetail(results.get(i),results,i,hasMore);
// }
// getGooglePhotos(results.get(1).getReference());
} else {
mAdapter.loadMoreEnd();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
5.请求某个地点对应的照片时:
private void getGooglePhotos(String photoreference) {
String baseUrlPhoto = "https://maps.googleapis.com/maps/api/place/photo?";
String realUrlPhoto = baseUrlPhoto + "maxwidth=480&photoreference=" + photoreference
+ "&key=" + "你的谷歌对应的key";
HBClient.getService(MineService.class).listGooglePhotos(realUrlPhoto).enqueue(new RequestCallBack() {
@Override
public void onFailed(Call call, Response response) {
super.onFailed(call, response);
}
@Override
public void onFailure(Call call, Throwable t) {
super.onFailure(call, t);
}
@Override
public void onSuccess(Call call, Response response) {
try {
String json = response.body().string();
LogUtil.e("图片json为" + json);
if (json != null && !json.equals("")) {
GoogleLocationBean bean = GsonUtils.jsonToBean(json, GoogleLocationBean.class);
if (bean == null) {
LogUtil.e("解析周边地址图片json为空");
} else {
if (bean.getStatus().equals("OK")) {
List results = bean.getResults();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
6.上述请求对应地点照片采用的Places的web的api,也可以采用安卓的api,如下:
private void getPhoto(String placeId, GoogleApiClient mGoogleApiClient, ImageView imgLogo) {
Places.GeoDataApi.getPlacePhotos(mGoogleApiClient, placeId)
.setResultCallback(photos -> {
if (!photos.getStatus().isSuccess()) {
return;
}
PlacePhotoMetadataBuffer photoMetadataBuffer = photos.getPhotoMetadata();
if (photoMetadataBuffer.getCount() > 0) {
// Display the first bitmap in an ImageView in the size of the view
photoMetadataBuffer.get(0)
.getScaledPhoto(mGoogleApiClient, imgLogo.getWidth(),
imgLogo.getHeight())
.setResultCallback(placePhotoResult -> {
LogUtil.e("请求图片回调-"+placePhotoResult.getStatus().isSuccess());
if (!placePhotoResult.getStatus().isSuccess()) {
return;
}
imgLogo.setImageBitmap(placePhotoResult.getBitmap());
});
}else {
LogUtil.e("查询到图片数量为0");
}
photoMetadataBuffer.release();
});
}
7.关于谷歌地图的显示的补充:在Activity中实现OnMapReadyCallback接口
在onCreate方法中:注意
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO: add setContentView(...) invocation
ButterKnife.bind(this);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
LogUtil.e("googleMap");
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// mMap.setOnMyLocationButtonClickListener(this);
// mMap.setOnMarkerDragListener(this);
UiSettings uiSettings = mMap.getUiSettings();
uiSettings.setZoomControlsEnabled(true);
uiSettings.setZoomGesturesEnabled(true);
uiSettings.setCompassEnabled(true);
uiSettings.setMyLocationButtonEnabled(true);//不显示定位按钮
// enableMyLocation();
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(item.getGeometry().getLocation().getLat(), item.getGeometry().getLocation().getLng());
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
MyApp.runOnUIThread(new Runnable() {
@Override
public void run() {
mMap.animateCamera(CameraUpdateFactory.
newLatLngZoom(new LatLng(item.getGeometry().getLocation().getLat(),
item.getGeometry().getLocation().getLng()), 16));
Marker melbourne = mMap.addMarker(new MarkerOptions()
.position(sydney)
.title(item.getVicinity()));
melbourne.showInfoWindow();
CircleOptions circleOptions = new CircleOptions()
.center(sydney)
.radius(280); // In meters
Circle circle = mMap.addCircle(circleOptions);
circle.setFillColor(Color.argb(45, 0, 191, 255));
circle.setStrokeColor(Color.argb(65, 0, 191, 255));
circle.setStrokeWidth(6);
}
});
}
}, 300);
}
}
对应的布局文件: