在刚学习使用百度地图,接着开始定位的运用时,又遇到了些问题,特此谨记!
学习了这位前辈的经验,少了很多弯路:http://blog.csdn.net/android_for_james/article/details/51533511
先看看运行效果
一.必须确定包名和百度地图申请时的一致,即:
不然会提示 230错误(APP Scode校验失败问题)
所谓的230错误,即为增强移动APP对百度开发SDK/API服务访问的控制,也避免恶意开发者对百度地图服务进行攻击,我们对Mobile类(Android/IOS)的服务请求进行了安全码校验;所谓安全码即开发者在API控制台申请AK(AK和APP一一对应)时提供的APP签名的SHA1+”;”+包名,请求服务必须要携带该安全码作为参数,不携带或者携带不一致的安全码给服务端,均会返回230错误。
二.需要调用的服务
将下列代码放在AndroidManifest文件的application中
<service
android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote" >
</service>
三.实现结构
1.MylocationListener负责定位操作
2.MyOrientationListener负责定位图标与方向传感器相结合
贴上MyOrientationListener类代码:
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
public class MyOrientationListener implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mSensor;
private Context mContext;
private float lastX;
private OnOrientationListener mOnOrientationListener;
public MyOrientationListener(Context context) {
this.mContext = context;
}
public void start() {
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
if (mSensorManager != null) {
//获得方向传感器
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
}
//判断是否有方向传感器
if (mSensor != null) {
//注册监听器
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_UI);
}
}
public void stop() {
mSensorManager.unregisterListener(this);
}
//方向改变
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
float x = event.values[SensorManager.DATA_X];
if (Math.abs(x - lastX) > 1.0) {
if (mOnOrientationListener != null) {
mOnOrientationListener.onOrientationChanged(x);
}
}
lastX = x;
}
}
public void setOnOrientationListener(OnOrientationListener listener) {
mOnOrientationListener = listener;
}
public interface OnOrientationListener {
void onOrientationChanged(float x);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
MainActivity类代码如下:
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.widget.Toast;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
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.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
public class MainActivity extends ActionBarActivity {
private MapView mMapView = null;
private BaiduMap mBaiduMap;
private LocationClient mlocationClient;
private MylocationListener mlistener;
private Context context;
private double mLatitude;
private double mLongitude;
private float mCurrentX;
//自定义图标
private BitmapDescriptor mIconLocation;
private MyOrientationListener myOrientationListener;
//定位图层显示方式
private MyLocationConfiguration.LocationMode locationMode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE);
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
this.context = this;
initView();
initLocation();
}
private void initView() {
mMapView = (MapView) findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
//根据给定增量缩放地图级别
MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);
mBaiduMap.setMapStatus(msu);
}
private void initLocation() {
locationMode = MyLocationConfiguration.LocationMode.NORMAL;
//定位服务的客户端。宿主程序在客户端声明此类,并调用,目前只支持在主线程中启动
mlocationClient = new LocationClient(this);
mlistener = new MylocationListener();
//注册监听器
mlocationClient.registerLocationListener(mlistener);
//配置定位SDK各配置参数,比如定位模式、定位时间间隔、坐标系类型等
LocationClientOption mOption = new LocationClientOption();
//设置坐标类型
mOption.setCoorType("bd09ll");
//设置是否需要地址信息,默认为无地址
mOption.setIsNeedAddress(true);
//设置是否打开gps进行定位
mOption.setOpenGps(true);
//设置扫描间隔,单位是毫秒 当<1000(1s)时,定时定位无效
int span = 1000;
mOption.setScanSpan(span);
//设置 LocationClientOption
mlocationClient.setLocOption(mOption);
//初始化图标,BitmapDescriptorFactory是bitmap 描述信息工厂类.
mIconLocation = BitmapDescriptorFactory.fromResource(R.drawable.location_marker);
myOrientationListener = new MyOrientationListener(context);
//通过接口回调来实现实时方向的改变
myOrientationListener.setOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
@Override
public void onOrientationChanged(float x) {
mCurrentX = x;
}
});
}
@Override
protected void onStart() {
//开启定位
mBaiduMap.setMyLocationEnabled(true);
if (!mlocationClient.isStarted()) {
mlocationClient.start();
}
myOrientationListener.start();
super.onStart();
}
@Override
protected void onStop() {
//停止定位
mBaiduMap.setMyLocationEnabled(false);
mlocationClient.stop();
myOrientationListener.stop();
super.onStop();
}
@Override
protected void onResume() {
mMapView.onResume();
super.onResume();
}
@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
//所有的定位信息都通过接口回调来实现
public class MylocationListener implements BDLocationListener {
//定位请求回调接口
private boolean isFirstIn = true;
//定位请求回调函数,这里面会得到定位信息
@Override
public void onReceiveLocation(BDLocation bdLocation) {
//BDLocation 回调的百度坐标类,内部封装了如经纬度、半径等属性信息
//MyLocationData 定位数据,定位数据建造器
/*
* 可以通过BDLocation配置如下参数
* 1.accuracy 定位精度
* 2.latitude 百度纬度坐标
* 3.longitude 百度经度坐标
* 4.satellitesNum GPS定位时卫星数目 getSatelliteNumber() gps定位结果时,获取gps锁定用的卫星数
* 5.speed GPS定位时速度 getSpeed()获取速度,仅gps定位结果时有速度信息,单位公里/小时,默认值0.0f
* 6.direction GPS定位时方向角度
* */
mLatitude = bdLocation.getLatitude();
mLongitude = bdLocation.getLongitude();
MyLocationData data = new MyLocationData.Builder()
.direction(mCurrentX)//设定图标方向
.accuracy(bdLocation.getRadius())//getRadius 获取定位精度,默认值0.0f
.latitude(mLatitude)//百度纬度坐标
.longitude(mLongitude)//百度经度坐标
.build();
//设置定位数据, 只有先允许定位图层后设置数据才会生效,参见 setMyLocationEnabled(boolean)
mBaiduMap.setMyLocationData(data);
//配置定位图层显示方式,三个参数的构造器
/*
* 1.定位图层显示模式
* 2.是否允许显示方向信息
* 3.用户自定义定位图标
* */
MyLocationConfiguration configuration
= new MyLocationConfiguration(locationMode, true, mIconLocation);
//设置定位图层配置信息,只有先允许定位图层后设置定位图层配置信息才会生效,参见 setMyLocationEnabled(boolean)
mBaiduMap.setMyLocationConfigeration(configuration);
//判断是否为第一次定位,是的话需要定位到用户当前位置
if (isFirstIn) {
//地理坐标基本数据结构
LatLng latLng = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
//描述地图状态将要发生的变化,通过当前经纬度来使地图显示到该位置
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
//改变地图状态
mBaiduMap.setMapStatus(msu);
isFirstIn = false;
Toast.makeText(context, bdLocation.getAddrStr(), Toast.LENGTH_SHORT).show();
}
}
}
}
博客中如有不当之处,希望各位可以不吝赐教,共同学习和探讨,谢谢!