今天分享一下如何在 Android 上发送地理位置消息。最终效果是这样的:
点击地理位置消息,可以进入地图,并在地图上显示位置标志:
接下来我们就来看看如何实现这一效果。
这个功能主要用到百度地图的定位和地图 SDK(当前版本为 v4.1.1),先来看一下布局界面:
activity_send_location.xml
可以看到界面非常简单,主体就是一个 MapView 和一个 ImageButton。
接下来是核心类 SendLocationActivity:
SendLocationActivity.java
...
mMapView = (MapView) findViewById(R.id.map_view);
Intent intent = getIntent();
boolean sendLocation = intent.getBooleanExtra("sendLocation", false);
mMap=mMapView.getMap();
mMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
mMap.setMyLocationEnabled(true);
mMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(18).build()));
mLocationClient = new LocationClient(getApplicationContext());
mLocationClient.registerLocationListener(mListener);
initLocation();
...
private void initLocation() {
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
option.setCoorType("bd09ll");
option.setScanSpan(1000);
option.setIsNeedAddress(true);
option.setOpenGps(true);
option.setIsNeedLocationDescribe(true);
option.setIsNeedLocationPoiList(true);
option.SetIgnoreCacheException(false);
option.setEnableSimulateGps(false);
mLocationClient.setLocOption(option);
}
上面主要是地图的初始化操作,通过
mLocationClient.registerLocationListener(mListener);
添加定位的接口回调,在获得定位后就回调用如下接口:
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
if (null == location || mMapView == null) {
return;
}
mLatitude = location.getLatitude();
mLongitude = location.getLongitude();
mDescribe = location.getLocationDescribe();
MyLocationData data = new MyLocationData.Builder()
.accuracy(location.getRadius())
.direction(100)
.latitude(mLatitude)
.longitude(mLongitude)
.build();
mMap.setMyLocationData(data);
if (mIsFirstLoc) {
mIsFirstLoc = false;
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
mMap.animateMapStatus(update);
Log.w("SendLocationActivity", location.getLocationDescribe());
}
}
}
上面的代码主要是在获得定位后刷新自己在地图上的定位(初始化设置了每隔一秒刷新一次),另外在地图上点击定位按钮,自己的位置就回移动到屏幕中心,点击事件如下:
mLocateBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LatLng ll = new LatLng(mLatitude, mLongitude);
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
mMap.animateMapStatus(update);
}
});
定位完成后就可以发送消息了,这时需要对自己的定位进行截图,BaiduMap 类提供了 snapshotScope 接口,这样就可以根据所传的矩阵来截取屏幕,而不必截取整个屏幕:
int left = mWidth / 4;int top = (int) (mHeight - 1.1 * mWidth);
Rect rect = new Rect(left, top, mWidth - left, mHeight - (int) (1.2 * top));
mMap.snapshotScope(rect, new BaiduMap.SnapshotReadyCallback() {
@Override
public void onSnapshotReady(Bitmap bitmap) {
if (null != bitmap && null != conv) {
LocationContent locationContent = new LocationContent(mLatitude,
mLongitude, mMapView.getMapLevel(), mDescribe);
String fileName = UUID.randomUUID().toString();
String path = BitmapLoader.saveBitmapToLocal(bitmap, fileName);
locationContent.setStringExtra("path", path);
...
}
}
}
另外,接受方收到消息,点击地理位置消息时,进入此界面,在地图上用一个图标来现实对方的位置,这是如何做到的呢,仅需要在 Map 上添加一个 Overlay 即可:
...
double latitude = intent.getDoubleExtra("latitude", 0);
double longitude = intent.getDoubleExtra("longitude", 0);
LatLng ll = new LatLng(latitude, longitude);
BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable.oval);
OverlayOptions options = new MarkerOptions().position(ll).icon(descriptor).zIndex(10);
mMap.addOverlay(options);
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
mMap.setMapStatus(update);
...
可以为这个图标添加点击事件,这样就可以做出显示对方位置的气泡效果:
mMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
if (mShowInfo) {
mMap.hideInfoWindow();
mShowInfo = false;
} else {
if (null == mInfoWindow) {
LatLng ll = marker.getPosition();
Point p = mMap.getProjection().toScreenLocation(ll);
p.y -= 47;
p.x -= 20;
LatLng llInfo = mMap.getProjection().fromScreenLocation(p);
mInfoWindow = new InfoWindow(mPopupView, llInfo, 0);
}
mMap.showInfoWindow(mInfoWindow);
mShowInfo = true;
}
return true;
}
});
以上就是关于地理位置消息的讲解。源码在 Github 上。