Android仿微信地图定位和位置选择(上)
Posted 一杯清泉
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android仿微信地图定位和位置选择(上)相关的知识,希望对你有一定的参考价值。
一、地图集成
集成腾讯地图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-data
android: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.MapView
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
2、搜索框控件布局
<EditText
android: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、进度条控件布局
<ProgressBar
android: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" />
三、绑定地图生命周期
@Override
public void onDestroy() {
mapView.onDestroy();
super.onDestroy();
tencentMap.removeTencentMapGestureListener(mapGestureListener);
}
@Override
public void onPause() {
mapView.onPause();
super.onPause();
}
@Override
public void onResume() {
mapView.onResume();
super.onResume();
}
@Override
public void onStop() {
mapView.onStop();
super.onStop();
}
@Override
public 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() {
@Override
public 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() {
@Override
public void onFinish() {
}
@Override
public 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。
由于内容比较长,地图的常用基本设置就到这里结束,下篇文章介绍剩余的内容。
以上是关于Android仿微信地图定位和位置选择(上)的主要内容,如果未能解决你的问题,请参考以下文章