一、地图集成
集成腾讯地图SDK,https://lbs.qq.com/,申请AppKey。
1、dependencies
implementation 'com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.2.6'
implementation 'com.tencent.map:tencent-map-vector-sdk:4.3.4'
2、AndroidManifest.xml
<application<meta-dataandroid:name="TencentMapSDK"android:value="*****-*****-*****-*****-*****-*****"/>
</application>
3、权限
<!--腾讯地图 SDK 要求的权限(开始)-->
<!--访问网络获取地图服务-->
<uses-permission android:name="android.permission.INTERNET"/>
<!--检查网络可用性-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 访问WiFi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--需要外部存储写权限用于保存地图缓存-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--获取 device id 辨别设备-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--腾讯地图 SDK 要求的权限(结束)-->
注意:这块除了AndroidManifest.xml权限之外还需要动态定义以下权限:
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION,
Manifest.permission.READ_PHONE_STATE
另外还需要打开手机定位功能:
public static void showSystemGPS(Activity activity) {if (!isOpenGPS()) {Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);WeDaActivity a = (WeDaActivity) activity;a.startActivityForResult(intent, ConstantUtils.REQUEST_SYSTEM_OPEN_GPS, (requestCode, resultCode, data) -> {if (isOpenGPS()) {UIUtils.showToast(activity, "GPS打开成功");} else {UIUtils.showToast(activity, "GPS打开失败");}});} else {UIUtils.showToast(activity, "GPS已经打开了");}
}public static boolean isOpenGPS() {LocationManager locationManager= (LocationManager) ApplicationUtils.getContext().getSystemService(Context.LOCATION_SERVICE);return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
4、混淆
-keep class com.tencent.tencentmap.**{*;}
-keep class com.tencent.map.**{*;}
-keep class com.tencent.beacontmap.**{*;}
-keep class navsns.**{*;}
-dontwarn com.qq.**
-dontwarn com.tencent.**
二、定义视图布局
1、地图控制布局
<com.tencent.tencentmap.mapsdk.maps.MapViewandroid:id="@+id/mapview"android:layout_width="fill_parent"android:layout_height="fill_parent" />
2、搜索框控件布局
<EditTextandroid:id="@+id/et_search"android:layout_width="match_parent"android:layout_height="33dp"android:layout_marginLeft="15dp"android:layout_marginTop="10dp"android:layout_marginRight="15dp"android:layout_marginBottom="10dp"android:layout_toLeftOf="@+id/tv_cancel_search"android:background="@drawable/shape_search_map"android:focusable="false"android:focusableInTouchMode="true"android:gravity="center"android:hint="@string/map_search_hint"android:imeOptions="actionSearch"android:inputType="text"android:paddingLeft="10dp"android:singleLine="true"android:textColor="@color/c_181818"android:textSize="15sp" />
3、进度条控件布局
<ProgressBarandroid:id="@+id/pb_progress"style="@android:style/Widget.Holo.ProgressBar"android:layout_width="70dp"android:layout_height="70dp"android:layout_gravity="center"android:visibility="visible" />
三、绑定地图生命周期
@Overridepublic void onDestroy() {mapView.onDestroy();super.onDestroy();tencentMap.removeTencentMapGestureListener(mapGestureListener);}@Overridepublic void onPause() {mapView.onPause();super.onPause();}@Overridepublic void onResume() {mapView.onResume();super.onResume();}@Overridepublic void onStop() {mapView.onStop();super.onStop();}@Overridepublic void onStart() {mapView.onStart();super.onStart();}
四、请求定位
1、创建定位请求对象
mapView = view.findViewById(R.id.mapview);
tencentMap = mapView.getMap();//创建地图请求对象
locationManager = TencentLocationManager.getInstance(context);
locationRequest = TencentLocationRequest.create();
locationRequest.setInterval(3000);
setInterval:用于设置连续定位的请求的间隔时间,这里设置3000毫秒回调一次。如果只需要定位一次,则调用locationManager.removeUpdates(this);取消连续定位回调。
2、请求定位信息
private void requestLocationUpdates() {int error = locationManager.requestLocationUpdates(locationRequest, LocationMapFragment.this);String des = "";switch (error) {case 0:des = "成功注册监听器";break;case 1:des = "设备缺少使用腾讯定位服务需要的基本条件";break;case 2:des = "manifest 中配置的 key 不正确";break;case 3:des = "自动加载libtencentloc.so失败";break;default:break;}LogUtils.d(des);
}
五、注册回调
1、实现地图相关接口
- LocationSource:页面显示和关闭的回调
- TencentLocationListener:连续定位获取位置信息的回调
(1)LocationSource
@Override
public void activate(OnLocationChangedListener arg0) {mChangedListener = arg0;//页面打开,请求定位信息requestLocationUpdates();
}@Override
public void deactivate() {//页面移出,清除位置回调locationManager.removeUpdates(this);locationManager = null;locationRequest = null;mChangedListener = null;
}
(2)TencentLocationListener
@Override
public void onLocationChanged(TencentLocation tencentLocation, int arg1, String arg2) {if (arg1 == TencentLocation.ERROR_OK && mChangedListener != null) { Location location = new Location(tencentLocation.getProvider());//设置经纬度location.setLatitude(tencentLocation.getLatitude());location.setLongitude(tencentLocation.getLongitude());//设置精度,这个值会被设置为定位点上表示精度的圆形半径location.setAccuracy(tencentLocation.getAccuracy());//设置定位标的旋转角度,注意 tencentLocation.getBearing() 只有在 gps 时才有可能获取location.setBearing((float) tencentLocation.getBearing());//将位置信息返回给地图mChangedListener.onLocationChanged(location);//移出回调,只请求一次,如果需要连续定位,删除这行代码locationManager.removeUpdates(this);} else {LogUtils.d("onLocationChanged error");}
}@Override
public void onStatusUpdate(String s, int i, String s1) {String desc = "";switch (i) {case TencentLocationListener.STATUS_DENIED:desc = "权限被禁止";break;case TencentLocationListener.STATUS_DISABLED:desc = "模块关闭";break;case TencentLocationListener.STATUS_ENABLED:desc = "模块开启";break;case TencentLocationListener.STATUS_GPS_AVAILABLE:desc = "GPS可用,代表GPS开关打开,且搜星定位成功";break;case TencentLocationListener.STATUS_GPS_UNAVAILABLE:desc = "GPS不可用,可能 gps 权限被禁止或无法成功搜星";break;case TencentLocationListener.STATUS_LOCATION_SWITCH_OFF:desc = "位置信息开关关闭,在android M系统中,此时禁止进行wifi扫描";break;default:break;}LogUtils.d("location status:" + s + ", " + s1 + " " + desc);
}
4、注册相关监听
//注册手势事件
tencentMap.addTencentMapGestureListener(mapGestureListener);
tencentMap.setLocationSource(this);
tencentMap.setMyLocationEnabled(true);
tencentMap.getUiSettings().setRotateGesturesEnabled(false);
//定位结果回调
tencentMap.setOnMyLocationChangeListener(onMyLocationChangeListener);private TencentMap.OnMyLocationChangeListener onMyLocationChangeListener = new TencentMap.OnMyLocationChangeListener() {@Overridepublic void onMyLocationChange(Location location) {LogUtils.d("内置定位标点击回调");if (!TextUtils.isEmpty(longitude) && !TextUtils.isEmpty(latitude)) {//传递的定位数据源Double lo = StringUtils.getDouble(longitude);Double la = StringUtils.getDouble(latitude);position = new LatLng(la, lo);longitude = null;latitude = null;} else {//GPS定位源position = new LatLng(location.getLatitude(), location.getLongitude());page = 1;}moveMap(position);presenter.setOriginLaLng(position);presenter.getNearAddress(position, page, fromMarker);}
};
setOnMyLocationChangeListener用户获取定位回调的结果,在注册TencentLocationListener接口后,调用requestLocationUpdates请求位置信息,触发onLocationChanged回调,在onLocationChanged中将事件通过mChangedListener.onLocationChanged传递给setOnMyLocationChangeListener回调。
这块有两个参数longitude、latitude是用户设置的坐标信息,如果用户传递了位置,则显示地图的中心点在该位置,否则设置当前位置的信息。
六、移动地图到中心点
private void moveMap(LatLng latLng) {//latLng中心点的坐标信息,15表示显示地图的缩放比例CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 15);tencentMap.animateCamera(cameraUpdate, new TencentMap.CancelableCallback() {@Overridepublic void onFinish() {}@Overridepublic void onCancel() {}});
}
七、设置Marker
marker的设置可以自定义,也可采用系统的。
private void setMarker(LatLng latLng) {//设置自定义marker样式
// MarkerOptions markerOptions = new MarkerOptions(latLng);
// markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_location_pin));
// markerOptions.visible(true);
// marker = tencentMap.addMarker(markerOptions);
// marker.setFixingPointEnable(true);//配置marker样式//HUE_BLUE:设置marker颜色为蓝色 MarkerOptions options = new MarkerOptions().icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE)).position(latLng);marker = tencentMap.addMarker(options);//设置marker固定到中心点LatLng target = tencentMap.getCameraPosition().target;//坐标系转换,坐标信息转换为屏幕的中心点信息markerPoint = tencentMap.getProjection().toScreenLocation(target);marker.setFixingPointEnable(true);marker.setFixingPoint(markerPoint.x, markerPoint.y);
}
注意:marker的设置需要在位置移动之后设置,因为moveMap是带有动画的异步操作,如果moveMap没执行完毕设置marker,则设置的marker无效,不显示;如果定位后手势缩放地图,则在地图上会出现多个marker。
由于内容比较长,地图的常用基本设置就到这里结束,下篇文章介绍剩余的内容。