本帖最后由 liu 于 2019-1-9 15:30 编辑
Android新手开发之旅目录
平时开发中经常会用到地图来定位,上一篇只是简单的说了下如何集成百度地图 http://www.sufeinet.com/thread-24744-1-1.html
本次在上篇的基础上来简单实现下如何定位和变更定位图标
定位:
1、初始化LocationClient类
[Java] 纯文本查看 复制代码 LocationClient locationClient = new LocationClient(getApplicationContext());
2、配置定位SDK参数
[Java] 纯文本查看 复制代码 //声明LocationClient类实例并配置定位参数
LocationClientOption locationOption = new LocationClientOption();
MyLocationListener myLocationListener = new MyLocationListener();
//注册监听函数
locationClient.registerLocationListener(myLocationListener);
//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
locationOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
locationOption.setCoorType("gcj02");
//可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
locationOption.setScanSpan(1000);
//可选,设置是否需要地址信息,默认不需要
locationOption.setIsNeedAddress(true);
//可选,设置是否需要地址描述
locationOption.setIsNeedLocationDescribe(true);
//可选,设置是否需要设备方向结果
locationOption.setNeedDeviceDirect(false);
//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
locationOption.setLocationNotify(true);
//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
locationOption.setIgnoreKillProcess(true);
//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
locationOption.setIsNeedLocationDescribe(true);
//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
locationOption.setIsNeedLocationPoiList(true);
//可选,默认false,设置是否收集CRASH信息,默认收集
locationOption.SetIgnoreCacheException(false);
//可选,默认false,设置是否开启Gps定位
locationOption.setOpenGps(true);
//可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用
locationOption.setIsNeedAltitude(false);
//设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者,该模式下开发者无需再关心定位间隔是多少,定位SDK本身发现位置变化就会及时回调给开发者
locationOption.setOpenAutoNotifyMode();
//设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者
locationOption.setOpenAutoNotifyMode(3000, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT);
//需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
locationClient.setLocOption(locationOption);
3、实现定位回调
[Java] 纯文本查看 复制代码 public class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
//此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
//以下只列举部分获取经纬度相关(常用)的结果信息
//更多结果信息获取说明,请参照类参考中BDLocation类中的说明
//获取纬度信息
double latitude = location.getLatitude();
//获取经度信息
double longitude = location.getLongitude();
// String addr = location.getAddrStr(); //获取详细地址信息
//String country = location.getCountry(); //获取国家
//String province = location.getProvince(); //获取省份
//String city = location.getCity(); //获取城市
//String district = location.getDistrict(); //获取区县
//String street = location.getStreet(); //获取街道信息
//float radius = location.getRadius(); //获取定位精度,默认值为0.0f
//String coorType = location.getCoorType(); //获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准
// int errorCode = location.getLocType(); //获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明
LatLng ll = new LatLng(latitude,
longitude);
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(18.0f);// 设置地图放大比例
mapView.setMapStatus(msu);
// 移动到某经纬度
mapView.animateMapStatus(update);
}
}
4、获取定位地址信息,调用LocationClient的start()方法,发起请求
[Java] 纯文本查看 复制代码 //开始定位
locationClient.start();
注意:别忘了在AndroidManifest.xml中添加定位权限<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
这样就可以定位到你的当前位置了
定位图标:
上面实现了定位功能,现在添加覆盖物来显示自己的位置
[Java] 纯文本查看 复制代码 //构建Marker图标 ,这里可以自己替换
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.pin_red);
//构建MarkerOption,用于在地图上添加Marker
OverlayOptions option = new MarkerOptions()
.position(ll) //传入经纬度
.icon(bitmap)
.zIndex(12)
.draggable(true);
//在地图上添加Marker,并显示
map.addOverlay(option);
这样就已经将图标加上去了
完整代码:
activity_main.xml;
[XML] 纯文本查看 复制代码 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.company.baidumap.MainActivity">
<com.baidu.mapapi.map.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" />
</LinearLayout>
MainActivity:
[Java] 纯文本查看 复制代码 import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
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.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
public class MainActivity extends AppCompatActivity {
private MapView mMapVew;
private BaiduMap mapView;
private static final int FINE_LOCATION = 100;
private LocationClient locationClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMapVew = (MapView) findViewById(R.id.map);
mapView = mMapVew.getMap();
checkPermission();
}
private void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, FINE_LOCATION);
} else {
location();
}
} else {
location();
}
}
private void location() {
//定位服务的客户端。宿主程序在客户端声明此类,并调用,目前只支持在主线程中启动
locationClient = new LocationClient(getApplicationContext());
//声明LocationClient类实例并配置定位参数
LocationClientOption locationOption = new LocationClientOption();
MyLocationListener myLocationListener = new MyLocationListener();
//注册监听函数
locationClient.registerLocationListener(myLocationListener);
//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
locationOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
locationOption.setCoorType("gcj02");
//可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
locationOption.setScanSpan(1000);
//可选,设置是否需要地址信息,默认不需要
locationOption.setIsNeedAddress(true);
//可选,设置是否需要地址描述
locationOption.setIsNeedLocationDescribe(true);
//可选,设置是否需要设备方向结果
locationOption.setNeedDeviceDirect(false);
//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
locationOption.setLocationNotify(true);
//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
locationOption.setIgnoreKillProcess(true);
//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
locationOption.setIsNeedLocationDescribe(true);
//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
locationOption.setIsNeedLocationPoiList(true);
//可选,默认false,设置是否收集CRASH信息,默认收集
locationOption.SetIgnoreCacheException(false);
//可选,默认false,设置是否开启Gps定位
locationOption.setOpenGps(true);
//可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用
locationOption.setIsNeedAltitude(false);
//设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者,该模式下开发者无需再关心定位间隔是多少,定位SDK本身发现位置变化就会及时回调给开发者
locationOption.setOpenAutoNotifyMode();
//设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者
locationOption.setOpenAutoNotifyMode(3000, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT);
//需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
locationClient.setLocOption(locationOption);
//开始定位
locationClient.start();
}
/**
* 实现定位回调
*/
public class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
//此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
//以下只列举部分获取经纬度相关(常用)的结果信息
//更多结果信息获取说明,请参照类参考中BDLocation类中的说明
//获取纬度信息
double latitude = location.getLatitude();
//获取经度信息
double longitude = location.getLongitude();
// String addr = location.getAddrStr(); //获取详细地址信息
//String country = location.getCountry(); //获取国家
//String province = location.getProvince(); //获取省份
//String city = location.getCity(); //获取城市
//String district = location.getDistrict(); //获取区县
//String street = location.getStreet(); //获取街道信息
//float radius = location.getRadius(); //获取定位精度,默认值为0.0f
//String coorType = location.getCoorType(); //获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准
// int errorCode = location.getLocType(); //获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明
LatLng ll = new LatLng(latitude,
longitude);
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(18.0f);// 设置地图放大比例
mapView.setMapStatus(msu);
//构建Marker图标 ,这里可以自己替换
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.marker);
//构建MarkerOption,用于在地图上添加Marker
OverlayOptions option = new MarkerOptions()
.position(ll)
.icon(bitmap)
.zIndex(12)
.draggable(true);
//在地图上添加Marker,并显示
mapView.addOverlay(option);
// 移动到某经纬度
mapView.animateMapStatus(update);
}
}
public void call() {
//检查权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//进入到这里代表没有权限.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
//已经禁止提示了
Toast.makeText(MainActivity.this, "您已禁止该权限,需要重新开启。", Toast.LENGTH_SHORT).show();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, FINE_LOCATION);
}
} else {
location();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
// TODO Auto-generated method stub
switch (requestCode) {
case FINE_LOCATION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
location();
} else {
call();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
locationClient.stop();
}
}
MyApplication:[Java] 纯文本查看 复制代码 import android.app.Application;
import com.baidu.mapapi.CoordType;
import com.baidu.mapapi.SDKInitializer;
/**
* Created by Administrator on 2019/1/8.
*/
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
SDKInitializer.initialize(this);
//自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.
//包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。
SDKInitializer.setCoordType(CoordType.BD09LL);
}
}
|