android百度地图开发


公司原来项目里有使用百度地图,是比较老的v2_1_0版本,在android5.0一下版本测试没什么问题,在5.0以上就会报错明明有mapview,但是却找不到,导致程序异常退出(android.view.InflateException: Binary XML file line #50: Error inflating class com.baidu.mapapi.map.MapView),网上找了好久发现好多人遇到一样的错误,但是确实不一样的问题,大多数人遇到的没有调用SDKInitializer.initialize(getApplicationContext());初始化。去百度地图论坛上发帖子,有人回我要我去更新到最新的版本,我原先也想过要更新到最新的百度地图的sdk,发现百度地图的改动挺大,就像图层ItemizedOverlay,最新的版本好像这个类被去掉了,好多的方法也有改动,于是想偷懒能不能再原来版本的基础上改一下就算了,毕竟改别人写的项目是很烦人的(特别是没有注释的情况下);最终还是选择就更新到最新的sdk,顺便学习一下百度地图开发。记录一下自己学习过程遇到的问题,和解决办法。
首先是创建应用和获取密匙,这里用到的签名方式是SHA1并不是申请qq和微信分享用到的md5签名


然后后将获得密匙配置到androidmanifest.xml文件中


还需要添加一个服务


发现去掉这个服务也能定位我当前的位置,难道我弄错了什么?

下面上正式代码
	MapView mMapView;
	/***
	 * 是否是第一次定位
	 */
	private volatile boolean isFristLocation = true;
	
	private List<Map<String, String>> datalist;
	/**
	 * 最新一次的经纬度
	 */
	private double mCurrentLantitude;
	private double mCurrentLongitude;
	/**
	 * 当前的精度
	 */
	private float mCurrentAccracy;
	/**
	 * 定位的客户端
	 */
	private LocationClient mLocationClient;
	/**
	 * 地图实例
	 */
	private BaiduMap mBaiduMap;
	/**
	 * 当前定位的模式
	 */
	private LocationMode mCurrentMode = LocationMode.NORMAL;
	/**
	 * 方向传感器的监听器
	 */
	private MyOrientationListener myOrientationListener;

	/**
	 * 定位的监听器
	 */
	public MyLocationListener mMyLocationListener;
	/**
	 * 方向传感器X方向的值
	 */
	private int mXDirection;
	
	private BitmapDescriptor mIconMaker;
	
	private View infoView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		//初始化
		SDKInitializer.initialize(getApplicationContext());
		setContentView(R.layout.environment_map_activity);
		mMapView = (MapView) this.findViewById(R.id.environment_map_View);
		mIconMaker = BitmapDescriptorFactory.fromResource(R.drawable.tip_red);
		// 第一次定位
		isFristLocation = true;
		// 获取地图控件引用
		// 获得地图的实例
		mBaiduMap = mMapView.getMap();
		//设置地图的缩放比
		MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(12.0f);
		mBaiduMap.setMapStatus(msu);
		// 初始化定位
		initMyLocation();
		// 初始化传感器
		initOritationListener();
				//设置地图点击事件
				initMapClickEvent();
		//添加图层标志点击事件 需要该类实现监听OnMarkerClickListener
		mBaiduMap.setOnMarkerClickListener(this);
	
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				Get_Gps();
			}
		}).start();

	}
private void initMapClickEvent()
	{
		mBaiduMap.setOnMapClickListener(new OnMapClickListener()
		{

			@Override
			public boolean onMapPoiClick(MapPoi arg0)
			{
				return false;
			}

			@Override
			public void onMapClick(LatLng arg0)
			{
				mBaiduMap.hideInfoWindow();

			}
		});
	}
private void initMyLocation() {
		// 定位初始化
		mLocationClient = new LocationClient(this);
		mMyLocationListener = new MyLocationListener();
		mLocationClient.registerLocationListener(mMyLocationListener);
		// 设置定位的相关配置
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);// 打开gps
		option.setCoorType("bd09ll"); // 设置坐标类型
		option.setScanSpan(1000);
		mLocationClient.setLocOption(option);
	}
<span style="white-space:pre">	</span>/**
	 * 定位回调监听
	 */
	public class MyLocationListener implements BDLocationListener {
		@Override
		public void onReceiveLocation(BDLocation location) {

			// map view 销毁后不在处理新接收的位置
			if (location == null || mMapView == null)
				return;
			// 构造定位数据
			MyLocationData locData = new MyLocationData.Builder()
					.accuracy(location.getRadius())
					// 此处设置开发者获取到的方向信息,顺时针0-360
					.direction(mXDirection).latitude(location.getLatitude())
					.longitude(location.getLongitude()).build();
			mCurrentAccracy = location.getRadius();
			// 设置定位数据
			mBaiduMap.setMyLocationData(locData);
			mCurrentLantitude = location.getLatitude();
			mCurrentLongitude = location.getLongitude();
			// 设置自定义图标
			BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory
					.fromResource(R.drawable.location_me);
			MyLocationConfiguration config = new MyLocationConfiguration(
					mCurrentMode, true, mCurrentMarker);
//			mBaiduMap.setMyLocationConfigeration(config);
			// 第一次定位时,将地图位置移动到当前位置
			if (isFristLocation) {
				isFristLocation = false;
				LatLng ll = new LatLng(location.getLatitude(),
						location.getLongitude());
				MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
				mBaiduMap.animateMapStatus(u);
			}
		}

	}

	/**
	 * 初始化方向传感器
	 */
	private void initOritationListener() {
		myOrientationListener = new MyOrientationListener(
				getApplicationContext());
		myOrientationListener
				.setOnOrientationListener(new OnOrientationListener() {
					@Override
					public void onOrientationChanged(float x) {
						mXDirection = (int) x;

						// 构造定位数据
						MyLocationData locData = new MyLocationData.Builder()
								.accuracy(mCurrentAccracy)
								// 此处设置开发者获取到的方向信息,顺时针0-360
								.direction(mXDirection)
								.latitude(mCurrentLantitude)
								.longitude(mCurrentLongitude).build();
						// 设置定位数据
						mBaiduMap.setMyLocationData(locData);
						// 设置自定义图标
						BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory
								.fromResource(R.drawable.location_me);
						MyLocationConfiguration config = new MyLocationConfiguration(
								mCurrentMode, true, mCurrentMarker);
//						mBaiduMap.setMyLocationConfigeration(config);

					}
				});
	}

 
 
 
 
	/**
	 * 初始化图层
	 */
	public void addInfosOverlay(List<Environment> infos) {
//		synchronized (mIconMaker) {
		mBaiduMap.clear();
		LatLng latLng = null;
		OverlayOptions overlayOptions = null;
		Marker marker = null;
		for (Environment info : infos) {
			// 位置
			latLng = new LatLng(info.getmLat(), info.getMlon());
			// 图标
			
				overlayOptions = new MarkerOptions().position(latLng)
						.icon(mIconMaker).zIndex(5);
			
			
			marker = (Marker) (mBaiduMap.addOverlay(overlayOptions));
			Bundle bundle = new Bundle();
			bundle.putSerializable("environment",environment);
			marker.setExtraInfo(bundle);
		}
//		}

	}
	/**
	 * 图层标志的点击事件
	*/
		@Override
	public boolean onMarkerClick(Marker marker) {
		// TODO Auto-generated method stub
		Environment info = (Environment) marker.getExtraInfo().get("info");

		InfoWindow mInfoWindow;

		// 将marker所在的经纬度的信息转化成屏幕上的坐标
		final LatLng ll = marker.getPosition();
		Point p = mBaiduMap.getProjection().toScreenLocation(ll);
		Log.e("000", "--!" + p.x + " , " + p.y);
//		p.y -= 47;
		LatLng llInfo = mBaiduMap.getProjection().fromScreenLocation(p);
		// 为弹出的InfoWindow添加点击事件
		mInfoWindow=new InfoWindow(getInfoWindoView(marker, info.getCode()), llInfo,-47);
		// 显示InfoWindow
		mBaiduMap.showInfoWindow(mInfoWindow);
		return true;
	}
这里点击图层标志infowindow的第一个参数是一个view对象,不符合我的要求,我要弹出一个自定义的view包含图片和文字
我自定义了一个方法 getInfoWindoView返回一个view对象
TextView map_tvname;
	TextView map_first;
	TextView map_data;
	ImageView map_img_great;
	ImageView map_img_good;
	ImageView map_img_bad;

	private View getInfoWindoView(final Marker marker, final String code) {
		if (null == infoView) {
			infoView = (ViewGroup) LayoutInflater.from(this).inflate(
					R.layout.pop_environment_indoor, null);
		}
		map_tvname = (TextView) infoView.findViewById(R.id.map_tvname);
		map_first = (TextView) infoView.findViewById(R.id.map_first);
		map_data = (TextView) infoView.findViewById(R.id.map_data);
		map_img_great = (ImageView) infoView.findViewById(R.id.map_img_great);
		map_img_good = (ImageView) infoView.findViewById(R.id.map_img_good);
		map_img_bad = (ImageView) infoView.findViewById(R.id.map_img_bad);
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				HttpPost httpPost = new HttpPost("url");
				List<NameValuePair> params = new ArrayList<NameValuePair>();
				params.add(new BasicNameValuePair("code", code));
				params.add(new BasicNameValuePair("key", ascllEncrypt.datedata()));

				try {
					httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
					HttpResponse httpResponse = new DefaultHttpClient()
							.execute(httpPost);
					if (httpResponse.getStatusLine().getStatusCode() == 200) {
						HttpEntity entity = httpResponse.getEntity();
						XMLUtils xmlUtils = new XMLUtils();
						datalist = xmlUtils.GetEnvironmentMapData(entity.getContent());
						Message message = mHandler.obtainMessage();
						message.what = 0x11;
						mHandler.sendMessage(message);
					}
				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ClientProtocolException e)
					e.printStackTrace();
				}
 
 
 这里代码确实有点乱,我也觉得很不爽,先这样看着吧 
private Handler mHandler = new Handler() {

		public void handleMessage(Message msg) {
			if (msg.what == 0x11) {
			//在这里做infowindow中view的设置
			map_tvname.setTextView();
				...
	}
差点忘了还有一些内容,设置定位间隔时间,一旦启动定位,会不断获取的定位,需要在onstop,onstart,onresume,ondestoy 方法中做一些操作,以及对BitmapDescriptor对象的回收
	@Override
	protected void onStart() {
		// 开启图层定位
		mBaiduMap.setMyLocationEnabled(true);
		if (!mLocationClient.isStarted()) {
			mLocationClient.start();
		}
		// 开启方向传感器
		myOrientationListener.start();
		super.onStart();
	}

	@Override
	protected void onStop() {
		// 关闭图层定位
		mBaiduMap.setMyLocationEnabled(false);
		mLocationClient.stop();

		// 关闭方向传感器
		myOrientationListener.stop();
		super.onStop();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		// 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
		mMapView.onDestroy();
		 mIconMaker.recycle();
		mMapView = null;
	}

	@Override
	protected void onResume() {
		super.onResume();
		// 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
		mMapView.onResume();
	}
还有一个方向传感器的监听类
public class MyOrientationListener implements SensorEventListener
{

	private Context context;
	private SensorManager sensorManager;
	private Sensor sensor;
	
	private float lastX ; 
	
	private OnOrientationListener onOrientationListener ; 

	public MyOrientationListener(Context context)
	{
		this.context = context;
	}

	public void start()
	{
		// 获得传感器管理器
		sensorManager = (SensorManager) context
				.getSystemService(Context.SENSOR_SERVICE);
		if (sensorManager != null)
		{
			// 获得方向传感器
			sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
		}
		// 注册
		if (sensor != null)
		{//SensorManager.SENSOR_DELAY_UI
			sensorManager.registerListener(this, sensor,
					SensorManager.SENSOR_DELAY_UI);
		}

	}

	public void stop()
	{
		sensorManager.unregisterListener(this);
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy)
	{
		
	}

	@Override
	public void onSensorChanged(SensorEvent event)
	{
		// 接受方向感应器的类型  
        if (event.sensor.getType() == Sensor.TYPE_ORIENTATION)  
        {  
            // 这里我们可以得到数据,然后根据需要来处理  
            float x = event.values[SensorManager.DATA_X];  
            
            if( Math.abs(x- lastX) > 1.0 )
            {
            	onOrientationListener.onOrientationChanged(x);
            }
//            Log.e("DATA_X", x+"");
            lastX = x ; 
            
        }  
	}
	
	public void setOnOrientationListener(OnOrientationListener onOrientationListener)
	{
		this.onOrientationListener = onOrientationListener ;
	}
	
	
	public interface OnOrientationListener 
	{
		void onOrientationChanged(float x);
	}

}

最后还遇到了一个问题,就是在4.4.2的测试机上测试,地图显示没问题,我用我的三星s6(系统版本是6.0,不知道其他版本什么情况)测了一下发现很坑爹的一件事,就是当前定位的图标(自己设置的图标)被放大了很多(如下图),而且图标是躺着的,折腾了一天,去百度地图的论坛问了,没人理我,网上也看了,也没有解决办法,于是我看了一下,我不设置图标,它会不会有默认的,结果是有的,就是把定位监听回调和初始化传感器中的自定义图标注释掉就可以的:
自定义图标
BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory.fromResource(R.drawable.location_me);
MyLocationConfiguration config = new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker);
mBaiduMap.setMyLocationConfigeration(config);
然后我就勉强用他的默认的了。如果大家有解决办法可以和我说,谢谢


写的不是很好,最重要的是记录自己学习的东西吧,把它写出来可能记得更好,也方便一些和我遇到一样问题的童鞋,一起交流,这其中很多代码借鉴张鸿洋大哥的博客,

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值