实验十二 百度地图 定位

一、实验目的

(1)学会配置百度地图开发环境

(2)能够定位到自己的所在位置

二、实验内容

利用百度地图资源开发自己的地图软件,实现定位自己所在位置的功能

三、实验结果图



四、实验代码

MainActivity:

package com.test12.mapdemo;

import java.util.List;

import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.BDNotifyListener;//假如用到位置提醒功能,需要import该类
import com.baidu.location.LocationClientOption.LocationMode;
import com.baidu.location.Poi;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;

public class MainActivity extends Activity {
	MapView mMapView = null;
	BaiduMap mMap;

	public LocationClient mLocationClient = null;
	public BDLocationListener myListener = new MyLocationListener();

	public class MyLocationListener implements BDLocationListener {
		 
		// 在本方法接收定位信息
		@Override
		public void onReceiveLocation(BDLocation location) {
			
			if (location != null) {
        		MyLocationData.Builder builder = new MyLocationData.Builder();
        		builder.accuracy(location.getRadius());		// 设置精度
        		builder.direction(location.getDirection());	// 设置方向
        		builder.latitude(location.getLatitude());	// 设置纬度
        		builder.longitude(location.getLongitude());	// 设置经度
				MyLocationData locationData = builder.build();
				mMap.setMyLocationData(locationData);	// 把定位数据显示到地图上
			}
			
			// Receive Location
			StringBuffer sb = new StringBuffer(256);
			sb.append("time : ");
			sb.append(location.getTime());
			sb.append("\nerror code : ");
			sb.append(location.getLocType());
			sb.append("\nlatitude : ");
			sb.append(location.getLatitude());
			sb.append("\nlontitude : ");
			sb.append(location.getLongitude());
			sb.append("\nradius : ");
			sb.append(location.getRadius());
			if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
				sb.append("\nspeed : ");
				sb.append(location.getSpeed());// 单位:公里每小时
				sb.append("\nsatellite : ");
				sb.append(location.getSatelliteNumber());
				sb.append("\nheight : ");
				sb.append(location.getAltitude());// 单位:米
				sb.append("\ndirection : ");
				sb.append(location.getDirection());// 单位度
				sb.append("\naddr : ");
				sb.append(location.getAddrStr());
				sb.append("\ndescribe : ");
				sb.append("gps定位成功");

			} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
				sb.append("\naddr : ");
				sb.append(location.getAddrStr());
				// 运营商信息
				sb.append("\noperationers : ");
				sb.append(location.getOperators());
				sb.append("\ndescribe : ");
				sb.append("网络定位成功");
			} else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
				sb.append("\ndescribe : ");
				sb.append("离线定位成功,离线定位结果也是有效的");
			} else if (location.getLocType() == BDLocation.TypeServerError) {
				sb.append("\ndescribe : ");
				sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
			} else if (location.getLocType() == BDLocation.TypeNetWorkException) {
				sb.append("\ndescribe : ");
				sb.append("网络不同导致定位失败,请检查网络是否通畅");
			} else if (location.getLocType() == BDLocation.TypeCriteriaException) {
				sb.append("\ndescribe : ");
				sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
			}
			sb.append("\nlocationdescribe : ");
			sb.append(location.getLocationDescribe());// 位置语义化信息
			List<Poi> list = location.getPoiList();// POI数据
			if (list != null) {
				sb.append("\npoilist size = : ");
				sb.append(list.size());
				for (Poi p : list) {
					sb.append("\npoi= : ");
					sb.append(p.getId() + " " + p.getName() + " " + p.getRank());
				}
			}
			Log.i("BaiduLocationApiDem", sb.toString());
		}
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 获取地图控件引用
		mMapView = (MapView) findViewById(R.id.bmapView);
		mMap = mMapView.getMap();

		mLocationClient = new LocationClient(getApplicationContext()); // 声明LocationClient类
		mLocationClient.registerLocationListener(myListener); // 注册监听函数
		initLocation();
		mMap.setMyLocationEnabled(true);	// 开启定位图层
	    setMyLocationConfigeration(MyLocationConfiguration.LocationMode.COMPASS); //指南针模式
	    mLocationClient.start();	// 开始定位
	}
	
	// 设置定位图层的配置 
	private void setMyLocationConfigeration(
			MyLocationConfiguration.LocationMode mode) {
		boolean enableDirection = true;	// 设置允许显示方向
	    BitmapDescriptor customMarker = BitmapDescriptorFactory.fromResource(R.drawable.local);	// 自定义定位的图标
	    MyLocationConfiguration config = new MyLocationConfiguration(mode, enableDirection, customMarker);
		mMap.setMyLocationConfigeration(config);
	}

	private void initLocation() {
		LocationClientOption option = new LocationClientOption();
		option.setLocationMode(LocationMode.Hight_Accuracy);// 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
		option.setCoorType("bd09ll");// 可选,默认gcj02,设置返回的定位结果坐标系
		int span = 1000;
		option.setScanSpan(span);// 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
		option.setIsNeedAddress(true);// 可选,设置是否需要地址信息,默认不需要
		option.setOpenGps(true);// 可选,默认false,设置是否使用gps
		option.setLocationNotify(true);// 可选,默认false,设置是否当GPS有效时按照1S/1次频率输出GPS结果
		option.setIsNeedLocationDescribe(true);// 可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
		option.setIsNeedLocationPoiList(true);// 可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
		option.setIgnoreKillProcess(false);// 可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
		option.SetIgnoreCacheException(false);// 可选,默认false,设置是否收集CRASH信息,默认收集
		option.setEnableSimulateGps(false);// 可选,默认false,设置是否需要过滤GPS仿真结果,默认需要
		mLocationClient.setLocOption(option);
	}

	@Override
	protected void onDestroy() {
		mLocationClient.stop();//停止定位
		super.onDestroy();
		// 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
		mMapView.onDestroy();
	}

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

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

MyApplication:

package com.test12.mapdemo;

import android.app.Application;

import com.baidu.mapapi.SDKInitializer;

public class MyApplication extends Application {

	@Override
	public void onCreate() {
		//在使用SDK各组件之前初始化context信息,传入ApplicationContext  
        //注意该方法要再setContentView方法之前实现  
        SDKInitializer.initialize(getApplicationContext()); 
	}
	
}

注意:在SDK各功能组件使用之前都需要调用

SDKInitializer.initialize(getApplicationContext());

因此我们建议该方法放在Application的初始化方法中



activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.test12.mapdemo.MainActivity" >

    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true" />

</RelativeLayout>

Manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test12.mapdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="14" />

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

    <!-- 这个权限用于进行网络定位 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
    </uses-permission>
    <!-- 这个权限用于访问GPS定位 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >
    </uses-permission>
    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
    </uses-permission>
    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
    </uses-permission>
    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
    </uses-permission>
    <!-- 用于读取手机当前的状态 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" >
    </uses-permission>
    <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
    </uses-permission>
    <!-- 访问网络,网络定位需要上网 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- SD卡读取权限,用户写入离线定位数据 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >
    </uses-permission>

    <application
        android:name=".MyApplication"
        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="tXgbbl59j3FricRRqhHkoN8ZCO5GXdoT" />

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote" >
        </service>
    </application>

</manifest>
这个密钥(key:tXgbbl59j3FricRRqhHkoN8ZCO5GXdoT)需要自己申请,百度搜索百度地图开放平台,可参考里面各种开发指南,链接见下方。

五、存在的问题

    目前,可以定位到你所处的位置,可以放大缩小,有方向,不过,无法随着屏幕的移动,指南针也跟着移动。以上所有资源都可以在http://developer.baidu.com/map/ 中找到,有几个要注意的问题,一个应用(一个包名)对应一个密钥,根据手机版本加入相应的jar包和so库(开发网站上均可下载),电脑上模拟器因为缺少GPS所以无法准确定位,一定要记得在manifest中添加权限。另外这只是一个Demo不是一个完整的应用。


    在获取用户位置时,优先使用GPS进行定位;如果GPS定位没有打开或者没有可用位置信息,则会通过判断网络是否连接(即确认手机是否能上网,不论是连接2G/3G或Wi-Fi网络),如果是,则通过请求百度网络定位服务,返回网络定位结果。为了使获得的网络定位结果更加精确,请打开手机的Wi-Fi开关。
    目前系统自带的网络定位服务精度低,且服务不稳定、精度低,并且从未来的趋势看,基站定位是不可控的(移动公司随时可能更改基站编号以垄断定位服务),而Wi-Fi定位则不然,它是一种精度更高、不受管制的定位方法。国内其它使用Wi-Fi定位的地图软件,Wi-Fi定位基本不可用,百度的定位服务量化指标优秀,网络接口返回速度快(服务端每次定位响应时间50毫秒以内),平均精度70米,其中Wi-Fi精度40米左右,基站定位精度200米左右,覆盖率98%,在国内处于一枝独秀的地位。


笔记:

百度地图核心类与方法
com.baidu.mapapi
SDKInitializer 初始化 SDK
com.baidu.mapapi.map  百度地图核心
MapView 显示地图的视图
getMap(); 获取地图控制器
addView(View, LayoutParams) MapViewLayoutParams,向MapView中添加一个子View,removeView(View)
showScaleControl(boolean) 是否显示比例尺控件
showZoomControls(boolean) 是否显示缩放控件
BaiduMap 专门操作MapView
setMapStatus(MapStatusUpdate) 更新地图状态
animateMapStatus(MapStatusUpdate) 以动画的方式更新地图状态
getMapStatus() 获取地图的当前状态
addOverlay(OverlayOptions) 向地图添加一个 Overlay
clear() 清空地图上所有的自定义覆盖物
setOnMarkerClickListener(BaiduMap.OnMarkerClickListener) 设置地图 Marker 覆盖物点击事件监听器
setOnMarkerDragListener(BaiduMap.OnMarkerDragListener) 设置 Marker 拖拽事件监听者
setMapType(int) 设置地图类型:普通图、卫星图
setTrafficEnabled(boolean) 是否打开交通图层
getMaxZoomLevel() 获取地图最大缩放级别
getMinZoomLevel() 获取地图最小缩放级别
getUiSettings() 获取地图ui控制器,可控制是否允许旋转、缩放、俯仰、拖拽等手势,是否允许指南针
setMyLocationEnabled(boolean) 设置是否允许定位图层
setMyLocationConfigeration(MyLocationConfiguration) 设置定位图层配置信息,只有先允许定位图层后设置定位图层配置信息才会生效
setMyLocationData(MyLocationData) 设置定位数据, 只有先允许定位图层后设置数据才会生效
snapshot(BaiduMap.SnapshotReadyCallback) 截图
UiSettings百度地图 UI 控制器(是否允许指南针、俯视手势、旋转手势、拖拽手势、缩放手势)
MapStatus 定义地图状态
MapStatusUpdate 描述地图状态将要发生的变化
MapStatusUpdateFactory 生成地图状态将要发生的变化
newLatLng(LatLng) 设置地图新中心点
zoomIn() 放大地图缩放级别
zoomOut() 缩小地图缩放级别
zoomTo(float) 设置地图缩放级别
newMapStatus(MapStatus) 设置地图新状态(俯仰、旋转、缩放、中心点等等)
CircleOptions  创建圆形覆盖物的选项
TextOptions  创建文字覆盖物的选项
MarkerOptions  创建Marker覆盖的选项
BitmapDescriptor  bitmap 描述信息
com.baidu.mapapi.model   JavaBean
LatLng 经伟度
LatLngBounds 地理范围:由西南、东北坐标组合起来的一个范围
com.baidu.mapapi.search.core  搜索核心
com.baidu.mapapi.search.poi  兴趣点搜索   
com.baidu.mapapi.search.route 路线搜索

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值