《Android 应用 之路》 百度地图API使用(4)

前言

百度地图的定位功能和基础地图功能是分开的,使用的是另外的jar包和so库文件,详情请关注官网:
百度定位SDK

配置

下载对应的jar包和so库,然后移动到lib目录下

AS中注意事项

1
2
3
4
5
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}

在application标签中声明service组件,每个app拥有自己单独的定位service

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

这个很重要 ,不要以为和基础地图的使用方式相同就忽略了对定位SDK配置官方说明的阅读

声明使用权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 这个权限用于进行网络定位-->
<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>

注意事项:
在Android6.0也就是M版本的手机上实现Demo时,由于M版本Google引入了动态权限分配的机制,如果没有在代码中申请权限,默认权限是不会被打开的,作为调试的注意事项,你需要到设置中手动的为Demo程序打开权限,方便定位能够正确的进行。

AK配置

参照基础地图使用的AK配置即可

Demo实现

布局文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context="mapdemo.example.com.selfbaidumap.MainActivity">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:layout_weight="3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/et_locationresult"/>
<Button
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/bt_locate"
android:text="定位"/>
</LinearLayout>
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />

</LinearLayout>

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
public class MainActivity extends AppCompatActivity {
private MapView bmapView;
private BitmapDescriptor bitmap = null;
private BaiduMap mBaiduMap = null;
private LocationClient mLocationClient = null;
private BDLocationListener myListener = new MyLocationListener();

private EditText editTextLocationResult;
private Button doLocateButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);

bmapView = (MapView) findViewById(R.id.bmapView);
mBaiduMap = bmapView.getMap();
//设置Marker的点击事件监听
mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
if (marker.getExtraInfo() != null) {
Bundle bundle = marker.getExtraInfo();//获取传递过来的信息
LatLng latlng = bundle.getParcelable("LatLng");//拿到经纬度
String address = bundle.getString("ADDRESS");//拿到地址信息
TextView tv = new TextView(MainActivity.this);
tv.setBackgroundResource(R.drawable.marker_info_bg);
tv.setTextColor(Color.WHITE);
tv.setText(address);
InfoWindow info = new InfoWindow(tv, latlng, -47);//创建弹出窗覆盖物
mBaiduMap.showInfoWindow(info);//展示
}
return false;
}
});

doLocateButton = (Button) findViewById(R.id.bt_locate);
doLocateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startLocate();//开始定位
}
});
editTextLocationResult = (EditText) findViewById(R.id.et_locationresult);
bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.icon_gcoding);
mLocationClient = new LocationClient(getApplicationContext()); //声明LocationClient类
mLocationClient.registerLocationListener(myListener); //注册监听函数
initLocation();//初始化定位的一些配置
}

private void initLocation() {
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.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有效时按照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仿真结果,默认需要
mLocationClient.setLocOption(option);
}

private void startLocate() {
if (mLocationClient != null) {
mLocationClient.start();//启动定位
}
}

@Override
protected void onResume() {
if (bmapView != null) {
bmapView.onResume();
}
super.onResume();
}

@Override
protected void onPause() {
if (bmapView != null) {
bmapView.onPause();
}
super.onPause();
}

@Override
protected void onDestroy() {
if (bmapView != null) {
bmapView.onDestroy();
}
if (bitmap != null) {
bitmap.recycle();
}
super.onDestroy();
}
//这个是从Demo中拿过来的,我自己使用的时候可以不同这么复杂,拿到对应的信息即可
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
//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());
editTextLocationResult.setText(location.getAddrStr());//显示查询结果
addMark(location.getLatitude(), location.getLongitude(), location.getAddrStr());//添加覆盖物
mLocationClient.stop();
}
}

private void addMark(double latitude, double longitude, String address) {
LatLng latlng = new LatLng(latitude, longitude);
Bundle bundle = new Bundle();
bundle.putString("ADDRESS", address);
bundle.putParcelable("LatLng", latlng);//创建Bundle传递,用于在点击的时候创建弹出窗
OverlayOptions option = new MarkerOptions().icon(bitmap).extraInfo(bundle).position(latlng);
if (mBaiduMap != null) {
mBaiduMap.addOverlay(option);
mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(latlng));//移动到new marker
}
}
}

实际效果
这里写图片描述
(个人地理位置信息被处理了,实际Demo以个人位置为准)

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×