今天要为相册管理app添加一个地图观察功能,
主要是点击listview的图片后展开百度地图并在地图上标记出对应的图片,
并在该位置覆盖一个图片固定大小缩略图的一个图层。
(最后只附上地图模块的代码)
百度地图API的使用步骤:
1. http://developer.baidu.com/map/ 在该链接登陆百度地图API后,在API控制台注册一个APP的APIKEY,注册时需要SHA1指纹,只需(若使用Eclipse):Window->Preferences->Android->Build中复制即可。(本文所用百度地图版本2.4.2)得到移动端APIKEY之后,在AndroidManifest.xml中的<application> 加入meta-data子项,具体如:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="hgxHPQiRTvaRAkUy3bS2EnDA"/>
下面附上使用最简单地图功能的一段代码:
package com.example.photomanager0;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.map.Ground;
import com.baidu.mapapi.map.GroundOverlay;
import com.baidu.mapapi.map.MKEvent;
import com.baidu.mapapi.map.MKMapTouchListener;
import com.baidu.mapapi.map.MKMapViewListener;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.utils.DistanceUtil;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Thumbnails;
import android.widget.Toast;
public class ShowMapActivity extends Activity{
Bitmap bitmap =null;
private Toast mToast;
private BMapManager mBMapManager;
private MapView mMapView = null;
private MapController mMapController = null;
private GeoPoint pPic;
MKMapViewListener mMapListener = null;
private GroundOverlay mGroundOverlay;
private Ground mGround;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBMapManager = new BMapManager(this.getApplication());
mBMapManager.init(new MKGeneralListener(){
@Override
public void onGetNetworkState(int arg0) {
// TODO Auto-generated method stub
if (arg0 == MKEvent.ERROR_PERMISSION_DENIED){
showToast("Wrong API KEY...");
}
}
@Override
public void onGetPermissionState(int arg0) {
// TODO Auto-generated method stub
if (arg0 == MKEvent.ERROR_NETWORK_CONNECT){
Toast.makeText(getApplication(), "Connecting Failed", Toast.LENGTH_LONG).show();
}
}
});
setContentView(R.layout.map_show);
Long id = getIntent().getLongExtra("com.example.photomanager0.image",-1);
BitmapFactory.Options op = new BitmapFactory.Options();
bitmap = ThumbnailUtils.extractThumbnail(MediaStore.Images.Thumbnails.getThumbnail(
ShowMapActivity.this.getContentResolver(), id, Thumbnails.MINI_KIND, op), 200, 200);
createScaledBitmap();
mMapView = (MapView) findViewById(R.id.bmapView);
mMapController = mMapView.getController();
mMapController.enableClick(true);
mMapController.setZoom(14);
mMapView.setBuiltInZoomControls(true);
GeoPoint p = new GeoPoint((int)(getIntent().getDoubleExtra("latitude", 39.945) * 1E6),
(int)(getIntent().getDoubleExtra("longitude", 116.404)*1E6));
pPic = p;
mMapController.setCenter(p);
initOverlay();
mMapView.regMapTouchListner(new MKMapTouchListener(){
@Override
public void onMapClick(GeoPoint arg0) {
// TODO Auto-generated method stub
if (DistanceUtil.getDistance(arg0, pPic)<250){
showToast("转到全景图模式...");
Intent intent = new Intent(ShowMapActivity.this, ShowPanoramaActivity.class);
intent.putExtra("x", pPic.getLatitudeE6());
intent.putExtra("y", pPic.getLongitudeE6());
startActivity(intent);
}
}
@Override
public void onMapDoubleClick(GeoPoint arg0) {
// TODO Auto-generated method stub
}
@Override
public void onMapLongClick(GeoPoint arg0) {
// TODO Auto-generated method stub
}
});
mMapListener = new MKMapViewListener() {
@Override
public void onMapMoveFinish() {
/**
* 在此处理地图移动完成回调
* 缩放,平移等操作完成后,此回调被触发
*/
}
@Override
public void onClickMapPoi(MapPoi mapPoiInfo) {
/**
* 在此处理底图poi点击事件
* 显示底图poi名称并移动至该点
* 设置过: mMapController.enableClick(true); 时,此回调才能被触发
*
*/
if (mapPoiInfo != null){
mMapController.animateTo(mapPoiInfo.geoPt);
}
}
@Override
public void onGetCurrentMap(Bitmap b) {
/**
* 当调用过 mMapView.getCurrentMap()后,此回调会被触发
* 可在此保存截图至存储设备
*/
}
@Override
public void onMapAnimationFinish() {
/**
* 地图完成带动画的操作(如: animationTo())后,此回调被触发
*/
}
/**
* 在此处理地图载完成事件
*/
@Override
public void onMapLoadFinish() {
showToast("加载完成");
}
};
}
public void initOverlay(){
/**
* 创建自定义overlay
*/
mGroundOverlay = new GroundOverlay(mMapView);
mGround = new Ground(bitmap, pPic, 500, 500);
mMapView.getOverlays().add(mGroundOverlay);
mGroundOverlay.addGround(mGround);
/**
* 刷新地图
*/
mMapView.refresh();
mMapView.regMapViewListener(mBMapManager, mMapListener);
}
@Override
protected void onResume(){
mMapView.onResume();
super.onResume();
}
@Override
protected void onPause() {
//MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
mMapView.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
//MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()
mMapView.destroy();
//退出应用调用BMapManager的destroy()方法
if(mBMapManager != null){
mBMapManager.destroy();
mBMapManager = null;
}
super.onDestroy();
}
private void createScaledBitmap(){
}
private void showToast(String msg){
if(mToast == null){
mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
}else{
mToast.setText(msg);
mToast.setDuration(Toast.LENGTH_SHORT);
}
mToast.show();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mMapView.onRestoreInstanceState(savedInstanceState);
}
}
效果如图所示:
需要注意的是,百度地图的一些类的初始化和资源的使用要求都需要谨慎,最好参考过百度的demo。
BMapManager如果没有初始化的化是一定要初始化的,它可以管理多个地图组件,另外要注意把map的生命周期和activity绑定,当我们退出时需要保证没有资源的泄露。
下面一段,是一个最简单的全景图的使用:
package com.example.photomanager0;
import com.baidu.mapapi.panorama.Panorama;
import com.baidu.mapapi.panorama.PanoramaLink;
import com.baidu.mapapi.panorama.PanoramaService;
import com.baidu.mapapi.panorama.PanoramaView;
import com.baidu.mapapi.panorama.PanoramaService.PanoramaServiceCallback;
import com.baidu.mapapi.panorama.PanoramaViewCamera;
import com.baidu.mapapi.panorama.PanoramaViewListener;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class ShowPanoramaActivity extends Activity{
private GeoPoint pPic;
private PanoramaView mPanoramaView;
private PanoramaService mService;
private PanoramaServiceCallback mCallback;
private ProgressDialog pd;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.panorama_show);
pPic = new GeoPoint(getIntent().getIntExtra("x", 0), getIntent().getIntExtra("y", 0));
Log.i("cursor_i", getIntent().getIntExtra("x", 0)+" "+getIntent().getIntExtra("y", 0));
pd = new ProgressDialog(this);
pd.setMessage("跳转中……");
pd.setCancelable(true);//设置进度条是否可以按退回键取消
mPanoramaView = (PanoramaView) findViewById(R.id.panorama);
mService = PanoramaService.getInstance(getApplicationContext());
mCallback = new PanoramaServiceCallback() {
public void onGetPanorama(Panorama p, int error) {
//使用pid进入时添加标注
if ( error != 0){
Toast.makeText(ShowPanoramaActivity.this,
"抱歉,未能检索到全景数据",Toast.LENGTH_LONG).show();
}
if (p != null) {
mPanoramaView.setPanorama(p);
}
}
};
mService.requestPanoramaByGeoPoint(pPic, mCallback);
mPanoramaView.setPanoramaViewListener(new PanoramaViewListener(){
@Override
public void afterMovetoPanorama(String arg0) {
// TODO Auto-generated method stub
pd.dismiss();
}
@Override
public void beforeMoveToPanorama(String arg0) {
// TODO Auto-generated method stub
pd.show();
}
@Override
public void onClickPanoramaLink(PanoramaLink arg0) {
// TODO Auto-generated method stub
}
@Override
public void onPanoramaAnimationEnd() {
// TODO Auto-generated method stub
}
@Override
public void onPanoramaAnimationStart() {
// TODO Auto-generated method stub
}
@Override
public void onPanoramaCameraChange(PanoramaViewCamera arg0) {
// TODO Auto-generated method stub
}
@Override
public void onPanoramaMoveFinish() {
// TODO Auto-generated method stub
}
@Override
public void onPanoramaMoveStart() {
// TODO Auto-generated method stub
}
});
}
@Override
protected void onPause() {
super.onPause();
mPanoramaView.onPause();
}
@Override
protected void onResume() {
super.onResume();
mPanoramaView.onResume();
}
@Override
protected void onDestroy() {
mPanoramaView.destroy();
mService.destroy();
super.onDestroy();
}
}
全景图部分主要由PanoramaView,PanoramaService,PanoramaServiceCallback 这三个部分组成:
PanoramaView完成对全景图的展示,而它的素材来源于PanoramaServiceCallback的回调函数提供的全景图,有了回调和位置pPic就可以建立一个PanoramaService完成对全景图服务的申请,笔者完成的Demo去掉了百度Demo中的一部分,可能较容易理解一些。最近好像3.0.0又去掉了全景图的功能,要使用全景图请下载2.4.2版本的百度地图。