最近开始学习android软件的开发设计,选择了做一个地图这个实用的app,研究了郭大神的《第一行代码》和社区的许多博主的文章,开始了自己的百度地图开发之旅。
由于社区和网上的文章代码大多基于很多年前百度地图刚开源时的地图SDK,android版本和java版本,实用性不高,但可以参考学习,将它变成自己的东西。
在这里带给大家本人在学习过程中遇到的问题的解决方法和开发经历,希望对后面的新人有所帮助。
经过漫长时间(几个月)的研究现在抽时间做个总结,如果只是初体验看这文章足够了,更深入的更改对于新人很麻烦,写起来也没法写,怪不得基本上没什么文章将深入开发。(个人感觉自己开发远不如直接关联拿来用,木有下篇我也很绝望呀)实习转前端了,现在开新坑了。。。。。
1.了解百度地图
由于百度地图早已开源,各位开发者可以去搜索引擎搜索“百度地图开发”,进入百度地图开放平台(传送门:点击打开链接)
首先开发文档里有着百度提供给我们的所有工具包,当然也有他们自己的demo(也仅仅只能拿来参考,非大佬怕是没法直接改了拿来用的):
我是用的是android地图SDK,根据自己的方案决定开发包的下载:
在控制台申请API:
到了第一个关键部分了
我使用的是最新版的eclipse和java包(都差不多)
如何获取SHA1?
打开eclipse->window->preferences->android->build就可以看到了。
至于eclipse上配置android环境大家都能百度到自己想要的结果,这里就不多说了(android SDk manger和 AVD是肯定要有的)
一定要先创建好android项目输入正确包名才行。
将下好的开发包解压后将内容复制到你项目中的libs文件夹里(没有的话自己建一个呗)
科普一下:前五个是百度提供的框架(AVD:虚拟机所适配的cpu类型)
将jar包import到你的项目里,准备就差不多了。
2.地图加载和定位
声明:使用android6.0版本
在AndroidManifest.xml里添加权限(具体就是英文的字面意思)
<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 android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
在<application 里加入
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="自己申请的key">
</meta-data>
<service
android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote" >
</service>
在res->layout->activity_main.xml里添加地图控件
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:clickable="true" >
</com.baidu.mapapi.map.MapView>
// 隐藏logo 加在Oncreate里即可
View child = mMapView.getChildAt(1);
if (child != null && (child instanceof ImageView || child instanceof ZoomControls)){
child.setVisibility(View.INVISIBLE);
}
//地图上比例尺
mMapView.showScaleControl(false);
// 隐藏缩放控件
mMapView.showZoomControls(false);
接下来就是主文件MainActivity.java
public class MainActivity extends Activity {
private MapView mMapView;// 用于显示地图的控件;
private BaiduMap baiduMap;
private boolean isFirstLocate = true;//
public LocationClient mLocationClient=null;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLocationClient=new LocationClient(getApplicationContext());//定义全局变量context
SDKInitializer.initialize(getApplicationContext());// 初始化地图SDK
setContentView(R.layout.activity_main);
mMapView = (MapView) findViewById(R.id.bmapView);// 绑定控件;
baiduMap = mMapView.getMap();
baiduMap.setMyLocationEnabled(true);
View child = mMapView.getChildAt(1);
if (child != null && (child instanceof ImageView || child instanceof ZoomControls)){
child.setVisibility(View.INVISIBLE);
}
mLocationClient = new LocationClient(getApplicationContext()); // 声明LocationClient类
mLocationClient.registerLocationListener(new MylocationListener()); // 注册监听函数
initLocation();
mLocationClient.start();
}
private void initLocation() {
// TODO Auto-generated method stub
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationMode.Hight_Accuracy);// 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
option.setCoorType("bd09ll");// 可选,默认gcj02,设置返回的定位结果坐标系
option.setScanSpan(3000);// 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(true);// 可选,设置是否需要地址信息,默认不需要
option.setOpenGps(true);// 可选,默认false,设置是否使用gps
option.setLocationNotify(true);// 可选,默认false,设置是否当gps有效时按照1S1次频率输出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仿真结果,默认需要
option.setNeedDeviceDirect(true);
mLocationClient.setLocOption(option);
}
public class MylocationListener implements BDLocationListener{
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null || mMapView == null) {
return;
}
MyLocationData locData = new MyLocationData.Builder().accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(location.getDirection())
.latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
baiduMap.setMyLocationData(locData);
if (isFirstLocate) {
isFirstLocate = false;
LatLng ll = new LatLng(location.getLatitude(),//确认地图是否第一次定位,只在第一次定位时才将地图转移到自己的位置
location.getLongitude());
MapStatus.Builder builder = new MapStatus.Builder();build//创建点
builder.target(ll).zoom(16.0f);
baiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
}
}
@Override
protected void onDestroy() {// 管理地图的生命周期:销毁
super.onDestroy();
mLocationClient.stop();//dingweitingzhi
mMapView.onDestroy();
baiduMap.setMyLocationEnabled(false);
}
@Override
protected void onResume() {// 显示;
super.onResume();
mMapView.onResume();
}
@Override
protected void onPause() {// 暂停;
super.onPause();
mMapView.onPause();
}
}
很多大佬都将地图转移的函数放到监听函数外面,虽然逻辑上正确,但是location值传递错误,每次打开就是一个天安门,很绝望。(也有可能是自己没理解对吧),不过无论怎么都获取不到方向信息,但也不影响(可能是自己手机的问题吧)
第一步就到这了,等到完成搜索功能再接后续吧。
代码只有参考功能,环境不一样,配置不正确都会造成很多错误,慢慢调试吧码农
完成全部代码后会提供下载