一 申请API key
- 在使用百度地图之前,我们必须去申请一个百度地图的API key,申请地址http://lbsyun.baidu.com/apiconsole/key,自己自行注册一个百度账号,很快就能申请到的,如下图
- 点击"创建密钥",系统将为我们自动生成密钥,当然我们在使用密钥之前还必须配置,点击"设置"如下图
Key type 选择“for mobile”,安全码是Android签名证书的证书指纹 (SHA1)值 + “;” + 你的应用程序包名,所以当你配置好了API key 你不能随意更换应用程序的包名, 如果更换了包名我们需要重新配置API key,接下来我们来介绍怎么获取数字签名
我们知道我们开发的Android程序是需要给他签名的,如果没有签名是不允许被安装到手机或者模拟器的,那么你会有疑问,我平常开发的应用确实没签名,怎么能在模拟器或者手机上直接运行呢,其实ADT会自动的使用debug密钥为应用程序签名,当然你也可以自己创建一个属于你自己的密钥,直接用Eclipse可视化创建就行了,很方便的,这里我就不介绍了
- 这里我们用debug.keystore来生成Android签名证书的证书指纹 (SHA1)值,可以在eclipse中直接查看:winows -> preferance -> android -> build。 如下图示:
然后我们使用keytool工具来获取签名证书的sha1值,在DOS输入keytool -list -keystore C:\Users\bds\.android\debug.keystore红色部分为debug.keystore的路径,接下来会要你输入输入密钥库口令,默认输入“android”,这样子我们就能获取证书指纹 (SHA1),如下图
红色框框里面的东西就是我们需要的Android签名证书的证书指纹 (SHA1)值,然后我们复制出来,输入到API key的安全码输入框里面,再用分号隔开加上你的应用程序包名,如 02:5C:80:25:B2:8F:6F:60:54:B9:F4:B2:EF:94:FF:EE:CC:3C:5A:29;com.example.baidumapdemo 这样子我们就配置好了API key
二、下载百度地图API库
要在Android应用中使用百度地图API,就需要在工程中引用百度地图API开发包,下载地址http://developer.baidu.com/map/sdkandev-download.htm,下载Android SDKv2.1.3 lib库就行了
三、在Android项目中引用百度地图
- 新建Android项目 BaiduMapDemo,然后将百度地图API库加入工程,如下图
第一步:在工程里新建libs文件夹,将开发包里的baidumapapi_vX_X_X.jar拷贝到libs根目录下,将libBaiduMapSDK_vX_X_X.so拷贝到libs\armeabi目录下(官网demo里已有这两个文件,如果要集成到自己的工程里,就需要自己添加),拷贝完成后的工程目录如下图所示;
第二步:在工程属性->Java Build Path->Libraries中选择“Add External JARs”,选定baidumapapi_vX_X_X.jar,确定后返回。
通过以上两步操作后,您就可以正常使用百度地图SDK为您提供的全部功能了。
注意:由于adt插件升级,若您使用Eclipse adt 22的话,需要对开发环境进行相应的设置,方法如下:
1. 在Eclipse 中选中工程,右键选 Properties->Java Build Path->Order and Export 使 Android Private Libraries处于勾选状态;
2. Project -> clean-> clean all .
Android Studio工程配置方法
第一步:在工程app/libs目录下放入baidumapapi_vX_X_X.jar包,在src/main/目录下新建jniLibs目录,工程会自动加载src目录下的so动态库,放入libBaiduMapSDK_vX_X_X_X.so如下图所示,注意jar和so的前3位版本号必须一致,并且保证使用一次下载的文件夹中的两个文件,不能不同功能组件的jar或so交叉使用。
so的配置也可以参考demo给出的目录结构,如下图所示,在app工程路径下,新建libs,并在libs目录下放入对应不同CPU架构的so文件。这样工程并不会自动加载libs下的so,需在gradle编译时,通过加入代码: jniLibs.srcDir 'libs' 来说明so的路径为该libs路径。
第二步:工程配置还需要把jar包集成到自己的工程中,如图上图所示,放入libs目录下。对于每个jar文件,右键-选择Add As Library,导入到工程中。对应在build.gradle生成工程所依赖的jar文件说明,如图所示:
jar的配置也可参考eclipse方法,进行以下操作:
菜单栏选择 File —>Project Structure。
在弹出的Project Structure 对话框中, 选择module, 然后点击 Dependencies 选项卡.
点击绿色的加号选择File dependency. 然后选择要添加的jar包即可 完成上边的操作后在app目录下的build.gradle文件中,会有引入的类库,如上图所示。
应用混淆
集成地图SDK的应用,在打包混淆的时候,需要注意与地图SDK相关的方法不可被混淆。混淆方法如下:
保证百度类不能被混淆,否则会出现网络不可用等运行时异常
xml 中代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.hhzmy.redbabydemo.ActivityBaiduMapMain">
<com.baidu.mapapi.map.MapView
android:id="@+id/id_bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginTop="80dip"
android:background="#D000"
android:minWidth="100dip"
android:orientation="vertical"
android:padding="2dp" >
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="定位icon" >
<RadioButton
android:id="@+id/defaulticon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="默认图标" >
</RadioButton>
<RadioButton
android:id="@+id/customicon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自定义图标" >
</RadioButton>
</RadioGroup>
</LinearLayout>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="25dp"
android:layout_marginTop="10dip" />
</RelativeLayout>
package com.hhzmy.redbabydemo; import android.Manifest; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.RadioGroup; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.BitmapDescriptor; import com.baidu.mapapi.map.BitmapDescriptorFactory; import com.baidu.mapapi.map.MapStatus; import com.baidu.mapapi.map.MapStatusUpdateFactory; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.MyLocationConfiguration; import com.baidu.mapapi.map.MyLocationData; import com.baidu.mapapi.model.LatLng; import com.example.redbabydemo.R; public class ActivityBaiduMapMain extends AppCompatActivity { private static final int ACCESS_COARSE_LOCATION_REQUEST_CODE = 1; // 定位相关 LocationClient mLocClient; public MyLocationListenner myListener = new MyLocationListenner(); private MyLocationConfiguration.LocationMode mCurrentMode; BitmapDescriptor mCurrentMarker; private static final int accuracyCircleFillColor = 0xAAFFFF88; private static final int accuracyCircleStrokeColor = 0xAA00FF00; MapView mMapView; BaiduMap mBaiduMap; // UI相关 RadioGroup.OnCheckedChangeListener radioButtonListener; Button requestLocButton; boolean isFirstLoc = true; // 是否首次定位 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //在使用SDK各组件之前初始化context信息,传入ApplicationContext //注意该方法要再setContentView方法之前实现 setContentView(R.layout.activity_activity_baidu_map_main); if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { //申请WRITE_EXTERNAL_STORAGE权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_COARSE_LOCATION_REQUEST_CODE); } else { init(); } } /** * 定位SDK监听函数 */ public class MyLocationListenner implements BDLocationListener { private SharedPreferences.Editor edit; private String str; @Override public void onReceiveLocation(BDLocation location) { // map view 销毁后不在处理新接收的位置 if (location == null || mMapView == null) { return; } //获取地址和纬度/*"定位的信息:" + location.getAddress().address + ",纬度:"+ location.getLatitude();*/ str = location.getAddrStr(); Log.i("-*----**-",str); Intent intent = new Intent(); intent.putExtra("address",str); // 设置结果,并进行传送 ActivityBaiduMapMain.this.setResult(0, intent); MyLocationData locData = new MyLocationData.Builder() .accuracy(location.getRadius()) // 此处设置开发者获取到的方向信息,顺时针0-360 .direction(100).latitude(location.getLatitude()) .longitude(location.getLongitude()).build(); mBaiduMap.setMyLocationData(locData); if (isFirstLoc) { isFirstLoc = false; LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); MapStatus.Builder builder = new MapStatus.Builder(); builder.target(ll).zoom(18.0f); mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build())); } } public void onReceivePoi(BDLocation poiLocation) { } } @Override protected void onPause() { mMapView.onPause(); super.onPause(); } @Override protected void onResume() { mMapView.onResume(); super.onResume(); } @Override protected void onDestroy() { // 退出时销毁定位 mLocClient.stop(); // 关闭定位图层 mBaiduMap.setMyLocationEnabled(false); mMapView.onDestroy(); mMapView = null; super.onDestroy(); } public void init(){ requestLocButton = (Button) findViewById(R.id.button1); mCurrentMode = MyLocationConfiguration.LocationMode.NORMAL; requestLocButton.setText("普通"); View.OnClickListener btnClickListener = new View.OnClickListener() { public void onClick(View v) { switch (mCurrentMode) { case NORMAL: requestLocButton.setText("跟随"); mCurrentMode = MyLocationConfiguration.LocationMode.FOLLOWING; mBaiduMap .setMyLocationConfigeration(new MyLocationConfiguration( mCurrentMode, true, mCurrentMarker)); break; case COMPASS: requestLocButton.setText("普通"); mCurrentMode = MyLocationConfiguration.LocationMode.NORMAL; mBaiduMap .setMyLocationConfigeration(new MyLocationConfiguration( mCurrentMode, true, mCurrentMarker)); break; case FOLLOWING: requestLocButton.setText("罗盘"); mCurrentMode = MyLocationConfiguration.LocationMode.COMPASS; mBaiduMap .setMyLocationConfigeration(new MyLocationConfiguration( mCurrentMode, true, mCurrentMarker)); break; default: break; } } }; requestLocButton.setOnClickListener(btnClickListener); RadioGroup group = (RadioGroup) this.findViewById(R.id.radioGroup); radioButtonListener = new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { if (checkedId == R.id.defaulticon) { // 传入null则,恢复默认图标 mCurrentMarker = null; mBaiduMap .setMyLocationConfigeration(new MyLocationConfiguration( mCurrentMode, true, null)); } if (checkedId == R.id.customicon) { // 修改为自定义marker mCurrentMarker = BitmapDescriptorFactory .fromResource(R.mipmap.ic_launcher); mBaiduMap .setMyLocationConfigeration(new MyLocationConfiguration( mCurrentMode, true, mCurrentMarker, accuracyCircleFillColor, accuracyCircleStrokeColor)); } } }; group.setOnCheckedChangeListener(radioButtonListener); // 地图初始化 mMapView = (MapView) findViewById(R.id.id_bmapView); mBaiduMap = mMapView.getMap(); // 开启定位图层 mBaiduMap.setMyLocationEnabled(true); // 定位初始化 mLocClient = new LocationClient(this); mLocClient.registerLocationListener(myListener); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true); // 打开gps option.setCoorType("bd09ll"); // 设置坐标类型 option.setScanSpan(1000); option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要 option.setIsNeedLocationDescribe(true);//可选,设置是否需要地址描述 option.setNeedDeviceDirect(false);//可选,设置是否需要设备方向结果 mLocClient.setLocOption(option); mLocClient.start(); } }
权限 :
百度地图SDK为开发者提供了便捷的显示百度地图数据的接口,通过以下几步操作,即可在您的应用中使用百度地图数据:
第一步:创建并配置工程(具体方法参见工程配置部分的介绍);
第二步:在AndroidManifest中添加开发密钥、所需权限等信息;
(1)在application中添加开发密钥
2)添加所需权限
第三步,在布局xml文件中添加地图控件;
第四步,在应用程序创建时初始化 SDK引用的Context 全局变量:
注意:在SDK各功能组件使用之前都需要调用
SDKInitializer.initialize(getApplicationContext());,因此我们建议该方法放在Application的初始化方法中
第五步,创建地图Activity,管理地图生命周期;
完成以上步骤后,运行程序,即可在您的应用中显示如下地图:
以上的例子为大家介绍了如何构建一个基础的地图页面。地图控件自v2.3.5版本起,支持多实例,即开发者可以在一个页面中建立多个地图对象,并且针对这些对象分别操作且不会产生相互干扰。具体使用方法请参考MutiMapViewDemo中的相关介绍。
此外,自v2.3.5版本开始。MapView控件还增加了对Fragment框架的支持。用户可以使用SupportMapFragment控件完成相应框架内的开发工作(详见MapFragmentDemo)。