android 百度地图系列之地图初始化及定位

来源:互联网 发布:design center 软件 编辑:程序博客网 时间:2024/05/17 03:48

在Android应用中,很多时候需要地图功能,回顾过去写的项目和百度地图api,开始总结一下Android百度地图的实现。首先总结一下怎么开始一个Android百度地图功能。
当使用百度地图的时候,提到一个appkey。“在使用百度地图SDK为您提供的各种LBS能力之前,您需要获取百度地图移动版的开发密钥,该密钥与您的百度账户相关联。因此,您必须先有百度帐户,才能获得开发密钥。并且,该密钥与您创建的过程名称有关。Key地址为:http://lbsyun.baidu.com/apiconsole/key”
这是百度地图api给的定义。总之,一个项目包名和sha1对应一个appkey。首先注册百度账号,根据教程一步步创建appkey。
当有了appkey,我们就能开一部署一个android百度地图环境。首先在百度api的相关下载中,将需要的功能勾选上,并下载相关的开发包,示例代码等。将开发包导入项目libs文件夹下。然后,开始部署AndroidMinifest.xml,添加权限,添加appkey,定位的service。

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="自己的包名"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="14"        android:targetSdkVersion="21" />    <!-- 百度地图权限 -->    <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.GET_TASKS" />    <uses-permission android:name="android.permission.WRITE_SETTINGS" />    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />    <!-- 这个权限用于进行网络定位 -->    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />    <!-- 这个权限用于访问GPS定位 -->    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />    <!-- 用于读取手机当前的状态 -->    <uses-permission android:name="android.permission.READ_PHONE_STATE" />    <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据 -->    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    <!-- 访问网络,网络定位需要上网 -->    <uses-permission android:name="android.permission.INTERNET" />    <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="申请的appkey" />        <activity            android:name=".MainActivity"            android:label="@string/app_name"            android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >            <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>

下一步就是在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" >    <com.baidu.mapapi.map.MapView          android:id="@+id/bmapView"          android:layout_width="fill_parent"          android:layout_height="fill_parent"          android:clickable="true" />    <ImageButton         android:id="@+id/ib_small"        android:layout_width="40dp"        android:layout_height="40dp"        android:background="@drawable/small"        android:layout_alignParentBottom="true"        android:layout_alignParentRight="true"        android:layout_marginRight="10dp"        android:layout_marginBottom="60dp"/>    <ImageButton        android:id="@+id/ib_large"        android:layout_width="40dp"        android:layout_height="40dp"        android:layout_above="@+id/ib_small"        android:layout_alignLeft="@+id/ib_small"        android:background="@drawable/large" />    <ImageButton        android:id="@+id/ib_mode"        android:layout_width="40dp"        android:layout_height="40dp"        android:layout_above="@+id/ib_large"        android:layout_alignLeft="@+id/ib_large"        android:layout_marginBottom="12dp"        android:background="@drawable/mode" />    <ImageButton        android:id="@+id/ib_traffic"        android:layout_width="40dp"        android:layout_height="40dp"        android:layout_above="@+id/ib_loc"        android:layout_alignLeft="@+id/ib_loc"        android:layout_marginBottom="12dp"        android:background="@drawable/offtraffic" />    <ImageButton        android:id="@+id/ib_loc"        android:layout_width="40dp"        android:layout_height="40dp"        android:layout_alignParentLeft="true"        android:layout_alignTop="@+id/ib_small"        android:layout_marginLeft="10dp"        android:background="@drawable/loc" /></RelativeLayout>

显示效果图:
这里写图片描述
下面开始具体的代码实现
当前程序有三个功能:显示地图,显示定位,实现按钮控制。

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //在使用SDK各组件之前初始化context信息,传入ApplicationContext          //注意该方法要再setContentView方法之前实现          SDKInitializer.initialize(getApplicationContext());          setContentView(R.layout.activity_main);          //初始化控件        initView();        //初始化地图        initMap();        //定位        initLocation();    }

一。显示基本地图
初始化地图显示,将地图在手机上显示出来

//获取地图控件引用  mMapView = (MapView) findViewById(R.id.bmapView);// 不显示缩放比例尺mMapView.showZoomControls(false);// 不显示百度地图LogomMapView.removeViewAt(1);//百度地图mBaiduMap = mMapView.getMap();// 改变地图状态,使地图显示在恰当的缩放大小MapStatus mMapStatus = new MapStatus.Builder().zoom(15).build();MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);mBaiduMap.setMapStatus(mMapStatusUpdate);

二。地图的控制按钮:缩放按钮,切换模式按钮,开启实时交通图
1.在地图初始化显示时,我将自带的缩放比例尺去掉了,需要自定义一个缩放按钮。
我们一般显示将地图显示在5-18级别中,所以在点击事件中对按钮进行了控制。

case R.id.ib_large:if (zoomLevel < 18) {    mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomIn());    ib_small.setEnabled(true);} else {    showInfo("已经放至最大,可继续滑动操作");    ib_large.setEnabled(false);}break;case R.id.ib_small:if (zoomLevel > 6) {    mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomOut());    ib_large.setEnabled(true);} else {    ib_small.setEnabled(false);    showInfo("已经缩至最小,可继续滑动操作");}break;

zoomlevel是一个全局变量,这时候就需要实时监控地图的缩放级别是多少,需要给地图添加一个地图状态改变的监听事件

//设置地图状态改变监听器mBaiduMap.setOnMapStatusChangeListener(new OnMapStatusChangeListener() {@Overridepublic void onMapStatusChangeStart(MapStatus arg0) {}@Overridepublic void onMapStatusChangeFinish(MapStatus arg0) {}@Overridepublic void onMapStatusChange(MapStatus arg0) {    //当地图状态改变的时候,获取放大级别    zoomLevel = arg0.zoom;}});

2.切换显示模式和实时交通图

boolean modeFlag = true;//设置初始时是普通模式case R.id.ib_mode://卫星模式和普通模式if(modeFlag){    modeFlag = false;    mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);    showInfo("开启卫星模式");}else{    modeFlag = true;    mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);    showInfo("开启普通模式");}break;case R.id.ib_traffic://是否开启交通图if(mBaiduMap.isTrafficEnabled()){//判断是否开启了交通图    mBaiduMap.setTrafficEnabled(false);    ib_traffic.setBackgroundResource(R.drawable.offtraffic);    showInfo("关闭实时交通图");}else{    mBaiduMap.setTrafficEnabled(true);    ib_traffic.setBackgroundResource(R.drawable.ontraffic);    showInfo("开启实时交通图");}break;

三。定位自己
定位自己的思路是:当程序启动的时候,开启定位图层,开始定位,收到位置信息后将自己的位置显示在地图中间,当地图离开自己的位置时,点击定位自己的图标将地图重新显示自己的位置。
首先,开启定位图层,开始定位。

@Overrideprotected void onStart() {    super.onStart();    //开启定位    mBaiduMap.setMyLocationEnabled(true);    if(!mLocationClient.isStarted()){//如果定位client没有开启,开启定位        mLocationClient.start();    }}private void initLocation() {    //定位客户端的设置    mLocationClient = new LocationClient(this);    mLocationListener = new MyLocationListener();    //注册监听    mLocationClient.registerLocationListener(mLocationListener);    //配置定位    LocationClientOption option = new LocationClientOption();    option.setCoorType("bd09ll");//坐标类型    option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要    option.setOpenGps(true);//打开Gps    option.setScanSpan(1000);//1000毫秒定位一次    option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到    mLocationClient.setLocOption(option);}//自定义的定位监听private class MyLocationListener implements BDLocationListener{    @Override    public void onReceiveLocation(BDLocation location) {        //将获取的location信息给百度map        MyLocationData data = new MyLocationData.Builder()                  .accuracy(location.getRadius())                  // 此处设置开发者获取到的方向信息,顺时针0-360                  .direction(100)                .latitude(location.getLatitude())                  .longitude(location.getLongitude())                .build();        mBaiduMap.setMyLocationData(data);        if(isFirstLocation){            //获取经纬度            LatLng ll = new LatLng(location.getLatitude(),location.getLongitude());            MapStatusUpdate status = MapStatusUpdateFactory.newLatLng(ll);            //mBaiduMap.setMapStatus(status);//直接到中间            mBaiduMap.animateMapStatus(status);//动画的方式到中间            isFirstLocation = false;            showInfo("位置:" + location.getAddrStr());        }    }}

注意,设置isFirstLocation=true,这样我们就只是开始的时候定位自己,并显示在地图中间,不会每一秒都跳一次。在我门需要定位的时候,将isFirstLocation重新设置成true就行。

case R.id.ib_loc:    isFirstLocation = true;    showInfo("返回自己位置");    break;

不要忘记在活动结束的时候,将定位取消

@Overrideprotected void onStop() {    super.onStop();    //关闭定位    mBaiduMap.setMyLocationEnabled(false);    if(mLocationClient.isStarted()){        mLocationClient.stop();    }}

然后运行程序,发现一个带有定位功能,并能部分控制地图显示的app出来了,下面是MainActivity的源码

package 包名;import com.baidu.location.BDLocation;import com.baidu.location.BDLocationListener;import com.baidu.location.LocationClient;import com.baidu.location.LocationClientOption;import com.baidu.mapapi.SDKInitializer;import com.baidu.mapapi.map.BaiduMap;import com.baidu.mapapi.map.BaiduMap.OnMapStatusChangeListener;import com.baidu.mapapi.map.MapStatus;import com.baidu.mapapi.map.MapStatusUpdate;import com.baidu.mapapi.map.MapStatusUpdateFactory;import com.baidu.mapapi.map.MapView;import com.baidu.mapapi.map.MyLocationData;import com.baidu.mapapi.model.LatLng;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.ImageButton;import android.widget.Toast;/** * 我的百度地图首页 * @author jing__jie * */public class MainActivity extends Activity implements OnClickListener {    private MapView mMapView = null;    private BaiduMap mBaiduMap;    private ImageButton ib_large,ib_small,ib_mode,ib_loc,ib_traffic;    //模式切换,正常模式    private boolean modeFlag = true;    //当前地图缩放级别    private float zoomLevel;     //定位相关    private LocationClient mLocationClient;    private MyLocationListener mLocationListener;    //是否第一次定位,如果是第一次定位的话要将自己的位置显示在地图 中间    private boolean isFirstLocation = true;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //在使用SDK各组件之前初始化context信息,传入ApplicationContext          //注意该方法要再setContentView方法之前实现          SDKInitializer.initialize(getApplicationContext());          setContentView(R.layout.activity_main);          //初始化控件        initView();        //初始化地图        initMap();        //定位        initLocation();    }      private void initMap() {        //获取地图控件引用          mMapView = (MapView) findViewById(R.id.bmapView);        // 不显示缩放比例尺        mMapView.showZoomControls(false);        // 不显示百度地图Logo        mMapView.removeViewAt(1);        //百度地图        mBaiduMap = mMapView.getMap();        // 改变地图状态        MapStatus mMapStatus = new MapStatus.Builder().zoom(15).build();        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);        mBaiduMap.setMapStatus(mMapStatusUpdate);        //设置地图状态改变监听器        mBaiduMap.setOnMapStatusChangeListener(new OnMapStatusChangeListener() {            @Override            public void onMapStatusChangeStart(MapStatus arg0) {            }            @Override            public void onMapStatusChangeFinish(MapStatus arg0) {            }            @Override            public void onMapStatusChange(MapStatus arg0) {                //当地图状态改变的时候,获取放大级别                zoomLevel = arg0.zoom;            }        });    }    private void initLocation() {        //定位客户端的设置        mLocationClient = new LocationClient(this);        mLocationListener = new MyLocationListener();        //注册监听        mLocationClient.registerLocationListener(mLocationListener);        //配置定位        LocationClientOption option = new LocationClientOption();        option.setCoorType("bd09ll");//坐标类型        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要        option.setOpenGps(true);//打开Gps        option.setScanSpan(1000);//1000毫秒定位一次        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到        mLocationClient.setLocOption(option);    }    private void initView() {        //地图控制按钮        ib_large = (ImageButton)findViewById(R.id.ib_large);        ib_large.setOnClickListener(this);        ib_small = (ImageButton)findViewById(R.id.ib_small);        ib_small.setOnClickListener(this);        ib_mode = (ImageButton)findViewById(R.id.ib_mode);        ib_mode.setOnClickListener(this);        ib_loc = (ImageButton)findViewById(R.id.ib_loc);        ib_loc.setOnClickListener(this);        ib_traffic = (ImageButton)findViewById(R.id.ib_traffic);        ib_traffic.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {        case R.id.ib_large:            if (zoomLevel < 18) {                mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomIn());                ib_small.setEnabled(true);            } else {                showInfo("已经放至最大,可继续滑动操作");                ib_large.setEnabled(false);            }            break;        case R.id.ib_small:            if (zoomLevel > 6) {                mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomOut());                ib_large.setEnabled(true);            } else {                ib_small.setEnabled(false);                showInfo("已经缩至最小,可继续滑动操作");            }            break;        case R.id.ib_mode://卫星模式和普通模式            if(modeFlag){                modeFlag = false;                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);                showInfo("开启卫星模式");            }else{                modeFlag = true;                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);                showInfo("开启普通模式");            }            break;        case R.id.ib_loc:            isFirstLocation = true;            showInfo("返回自己位置");            break;        case R.id.ib_traffic://是否开启交通图            if(mBaiduMap.isTrafficEnabled()){                mBaiduMap.setTrafficEnabled(false);                ib_traffic.setBackgroundResource(R.drawable.offtraffic);                showInfo("关闭实时交通图");            }else{                mBaiduMap.setTrafficEnabled(true);                ib_traffic.setBackgroundResource(R.drawable.ontraffic);                showInfo("开启实时交通图");            }            break;        default:            break;        }    }      @Override    protected void onStart() {        super.onStart();        //开启定位        mBaiduMap.setMyLocationEnabled(true);        if(!mLocationClient.isStarted()){            mLocationClient.start();        }    }    @Override    protected void onStop() {        super.onStop();        //关闭定位        mBaiduMap.setMyLocationEnabled(false);        if(mLocationClient.isStarted()){            mLocationClient.stop();        }    }    @Override      protected void onDestroy() {          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();      }    //显示消息    private void showInfo(String str){        Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();    }    //自定义的定位监听    private class MyLocationListener implements BDLocationListener{        @Override        public void onReceiveLocation(BDLocation location) {            //将获取的location信息给百度map            MyLocationData data = new MyLocationData.Builder()                      .accuracy(location.getRadius())                      // 此处设置开发者获取到的方向信息,顺时针0-360                      .direction(100)                    .latitude(location.getLatitude())                      .longitude(location.getLongitude())                    .build();            mBaiduMap.setMyLocationData(data);            if(isFirstLocation){                //获取经纬度                LatLng ll = new LatLng(location.getLatitude(),location.getLongitude());                MapStatusUpdate status = MapStatusUpdateFactory.newLatLng(ll);                //mBaiduMap.setMapStatus(status);//直接到中间                mBaiduMap.animateMapStatus(status);//动画的方式到中间                isFirstLocation = false;                showInfo("位置:" + location.getAddrStr());            }        }    }}

最后寄语,转载请注明出处,代码还要自敲,不要图快,一位的复制粘贴。

2 0