请问用手机安卓应用“百度地图”进行导航,如何才能设置指南针指针方向向永远指北,而不是随车头动?

118267人阅读
Android 百度地图开发(2)
转载请注明出处这一篇文章主要讲解的是百度地图的定位功能,然后还有MyLocationOverlay和PopupOverlay两个地图覆盖物的使用,Overlay是“图层”或“覆盖物”的意思,MyLocationOverlay从名字上面理解就是我的位置图层,他能够实现在地图上显示当前位置的图标以及指南针,MyLocationOverlay只负责显示我的位置,位置数据请使用百度定位SDK获取,将获取的位置数据放在一个LocationData结构中并用该结构设置MyLcationOverlay的数据源,即可创建MyLocationOverlay,PopupOverlay就是弹出窗口图层了,跟PopupWindow类似的东西,下面会介绍他们的使用方法定位我们使用的是百度&Android 定位SDKv4.0,我们先了解下定位原理和定位精度定位原理使用百度Android定位SDK必须注册GPS和网络使用权限。定位SDK采用GPS、基站、Wi-Fi信号进行定位。当应用程序向定位SDK发起定位请求时,定位SDK会根据应用的定位因素(GPS、基站、Wi-Fi信号)的实际情况(如是否开启GPS、是否连接网络、是否有信号等)来生成相应定位依据进行定位。用户可以设置满足自身需求的定位依据:若用户设置GPS优先,则优先使用GPS进行定位,如果GPS定位未打开或者没有可用位置信息,且网络连接正常,定位SDK则会返回网络定位(即Wi-Fi与基站)的最优结果。为了使获得的网络定位结果更加精确,请打开手机的Wi-Fi开关。定位精度了解了百度定位的原理和定位精度之后,接下来我们就来使用百度定位SDKv4.0吧一 . 导入库文件在使用百度定位SDKv4.0之前,我们要下载最新的库文件,下载地址:,将liblocSDK4.so文件拷贝到libs/armeabi目录下。将locSDK4.0.jar文件拷贝到工程的libs目录下二 . 布局文件,一个百度地图控件,加一个手动点击实现定位的按钮,放在一个相对布局里面,很简单的布局&?xml version=&1.0& encoding=&utf-8&?&
&RelativeLayout xmlns:android=&/apk/res/android&
android:layout_width=&fill_parent&
android:layout_height=&fill_parent& &
&com.baidu.mapapi.map.MapView
android:id=&@+id/bmapView&
android:layout_width=&fill_parent&
android:layout_height=&fill_parent&
android:clickable=&true& /&
android:id=&@+id/request&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_alignParentRight=&true&
android:layout_alignParentTop=&true&
android:layout_marginRight=&10dp&
android:layout_marginTop=&10dip&
android:background=&@drawable/custom_loc&
&/RelativeLayout&三 . 界面MainActivity代码,先贴上,然后适当讲解相关代码,我注释也比较清楚package com.example.
import android.app.A
import android.graphics.B
import android.os.B
import android.util.L
import android.view.LayoutI
import android.view.V
import android.view.View.MeasureS
import android.view.View.OnClickL
import android.widget.B
import android.widget.TextV
import android.widget.T
import com.baidu.location.BDL
import com.baidu.location.BDLocationL
import com.baidu.location.LocationC
import com.baidu.location.LocationClientO
import com.baidu.mapapi.BMapM
import com.baidu.mapapi.MKGeneralL
import com.baidu.mapapi.map.LocationD
import com.baidu.mapapi.map.MKE
import com.baidu.mapapi.map.MapC
import com.baidu.mapapi.map.MapV
import com.baidu.mapapi.map.MyLocationO
import com.baidu.mapapi.map.PopupClickL
import com.baidu.mapapi.map.PopupO
import com.api.basestruct.GeoP
public class MainActivity extends Activity {
private Toast mT
private BMapManager mBMapM
private MapView mMapView =
private MapController mMapController =
* 定位SDK的核心类
private LocationClient mLocC
* 用户位置信息
private LocationData mLocD
* 我的位置图层
private LocationOverlay myLocationOverlay =
* 弹出窗口图层
private PopupOverlay mPopupOverlay
private boolean isRequest =//是否手动触发请求定位
private boolean isFirstLoc =//是否首次定位
* 弹出窗口图层的View
private View mPopupV
private BDL
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//使用地图sdk前需先初始化BMapManager,这个必须在setContentView()先初始化
mBMapManager = new BMapManager(this);
//第一个参数是API key,
//第二个参数是常用事件监听,用来处理通常的网络错误,授权验证错误等,你也可以不添加这个回调接口
mBMapManager.init(&7aea513eaa7a17b9413b4b&, new MKGeneralListenerImpl());
setContentView(R.layout.activity_main);
//点击按钮手动请求定位
((Button) findViewById(R.id.request)).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
requestLocation();
mMapView = (MapView) findViewById(R.id.bmapView); //获取百度地图控件实例
mMapController = mMapView.getController(); //获取地图控制器
mMapController.enableClick(true);
//设置地图是否响应点击事件
mMapController.setZoom(14);
//设置地图缩放级别
mMapView.setBuiltInZoomControls(true);
//显示内置缩放控件
mMapView.setTraffic(true);
//设置交通信息图
mMapView.setSatellite(true);
//设置卫星图
mMapController.setOverlooking(-45);
//设置地图俯视角度 ,范围:0~ -45
mPopupView = LayoutInflater.from(this).inflate(R.layout.pop_layout, null);
//实例化弹出窗口图层
mPopupOverlay = new PopupOverlay(mMapView ,new PopupClickListener() {
* 点击弹出窗口图层回调的方法
public void onClickedPopup(int arg0) {
//隐藏弹出窗口图层
mPopupOverlay.hidePop();
//实例化定位服务,LocationClient类必须在主线程中声明
mLocClient = new LocationClient(getApplicationContext());
mLocClient.registerLocationListener(new BDLocationListenerImpl());//注册定位监听接口
* LocationClientOption 该类用来设置定位SDK的定位方式。
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); //打开GPRS
option.setAddrType(&all&);//返回的定位结果包含地址信息
option.setCoorType(&bd09ll&);//返回的定位结果是百度经纬度,默认值gcj02
option.setPriority(LocationClientOption.GpsFirst); // 设置GPS优先
option.setScanSpan(5000); //设置发起定位请求的间隔时间为5000ms
option.disableCache(false);//禁止启用缓存定位
option.setPoiNumber(5);
//最多返回POI个数
option.setPoiDistance(1000); //poi查询距离
option.setPoiExtraInfo(true);
//是否需要POI的电话和地址等详细信息
mLocClient.setLocOption(option);
//设置定位参数
mLocClient.start();
// 调用此方法开始定位
//定位图层初始化
myLocationOverlay = new LocationOverlay(mMapView);
//实例化定位数据,并设置在我的位置图层
mLocData = new LocationData();
myLocationOverlay.setData(mLocData);
//添加定位图层
mMapView.getOverlays().add(myLocationOverlay);
//修改定位数据后刷新图层生效
mMapView.refresh();
* 定位接口,需要实现两个方法
* @author xiaanming
public class BDLocationListenerImpl implements BDLocationListener {
* 接收异步返回的定位结果,参数是BDLocation类型参数
public void onReceiveLocation(BDLocation location) {
if (location == null) {
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){
sb.append(&\nspeed : &);
sb.append(location.getSpeed());
sb.append(&\nsatellite : &);
sb.append(location.getSatelliteNumber());
} else if (location.getLocType() == BDLocation.TypeNetWorkLocation){
sb.append(&\naddr : &);
sb.append(location.getAddrStr());
Log.e(&log&, sb.toString());
MainActivity.this.location =
mLocData.latitude = location.getLatitude();
mLocData.longitude = location.getLongitude();
//如果不显示定位精度圈,将accuracy赋值为0即可
mLocData.accuracy = location.getRadius();
mLocData.direction = location.getDerect();
//将定位数据设置到定位图层里
myLocationOverlay.setData(mLocData);
//更新图层数据执行刷新后生效
mMapView.refresh();
if(isFirstLoc || isRequest){
//将给定的位置点以动画形式移动至地图中心
mMapController.animateTo(new GeoPoint(
(int) (location.getLatitude() * 1e6), (int) (location
.getLongitude() * 1e6)));
showPopupOverlay(location);
isRequest =
isFirstLoc =
* 接收异步返回的POI查询结果,参数是BDLocation类型参数
public void onReceivePoi(BDLocation poiLocation) {
//继承MyLocationOverlay重写dispatchTap方法
private class LocationOverlay extends MyLocationOverlay{
public LocationOverlay(MapView arg0) {
super(arg0);
* 在“我的位置”坐标上处理点击事件。
protected boolean dispatchTap() {
//点击我的位置显示PopupOverlay
showPopupOverlay(location);
return super.dispatchTap();
* 显示弹出窗口图层PopupOverlay
* @param location
private void showPopupOverlay(BDLocation location){
TextView popText = ((TextView)mPopupView.findViewById(R.id.location_tips));
popText.setText(&[我的位置]\n& + location.getAddrStr());
mPopupOverlay.showPopup(getBitmapFromView(popText),
new GeoPoint((int)(location.getLatitude()*1e6), (int)(location.getLongitude()*1e6)),
* 手动请求定位的方法
public void requestLocation() {
isRequest =
if(mLocClient != null && mLocClient.isStarted()){
showToast(&正在定位......&);
mLocClient.requestLocation();
Log.d(&log&, &locClient is null or not started&);
* 显示Toast消息
* @param msg
private void showToast(String msg){
if(mToast == null){
mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
mToast.setText(msg);
mToast.setDuration(Toast.LENGTH_SHORT);
mToast.show();
* 将View转换成Bitmap的方法
* @param view
public static Bitmap getBitmapFromView(View view) {
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
* 常用事件监听,用来处理通常的网络错误,授权验证错误等
* @author xiaanming
public class MKGeneralListenerImpl implements MKGeneralListener{
* 一些网络状态的错误处理回调函数
public void onGetNetworkState(int iError) {
if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
showToast(&您的网络出错啦!&);
* 授权错误的时候调用的回调函数
public void onGetPermissionState(int iError) {
if (iError ==
MKEvent.ERROR_PERMISSION_DENIED) {
showToast(&API KEY错误, 请检查!&);
protected void onResume() {
//MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
mMapView.onResume();
super.onResume();
protected void onPause() {
//MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
mMapView.onPause();
super.onPause();
protected void onDestroy() {
//MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()
mMapView.destroy();
//退出应用调用BMapManager的destroy()方法
if(mBMapManager != null){
mBMapManager.destroy();
mBMapManager =
//退出时销毁定位
if (mLocClient != null){
mLocClient.stop();
super.onDestroy();
}LocationClient&定位SDK的核心类,LocationClient类必须在主线程中声明。需要Context类型的参数。Context需要时全进程有效的context,推荐用getApplicationConext获取全进程有效的context,我们调用registerLocationListener(BDLocationListener)方法来注册定位监听接口,BDLocationListener里面有两个方法,onReceiveLocation()(接收异步返回的定位结果),onReceivePoi()(接收异步返回的POI查询结果,POI是“Point of Interest”的缩写,可以翻译成“信息点”,每个POI包含四方面信息,名称、类别、经度、纬度、附近的酒店、饭店,商铺等信息。我们可以叫它为“导航地图信息”,导航地图数据是整个导航产业的基石),我们这里只需要重写onReceiveLocation就行了BDLocation&封装了定位SDK的定位结果,在BDLocationListener的onReceive方法中获取。通过该类用户可以获取error code,位置的坐标,精度半径,地址等信息,对于其getLocType ()方法获取的error code一些情况61 : GPS定位结果62 : 扫描整合定位依据失败。此时定位结果无效。63 : 网络异常,没有成功向服务器发起请求。此时定位结果无效。65 : 定位缓存的结果。66 : 离线定位结果。通过requestOfflineLocaiton调用时对应的返回结果67 : 离线定位失败。通过requestOfflineLocaiton调用时对应的返回结果68 : 网络连接失败时,查找本地离线定位时对应的返回结果161: 表示网络定位结果162~167: 服务端定位失败LocationClientOption 用来设置定位SDK的定位方式,比如设置打开GPS,设置是否需要地址信息,设置发起定位请求的间隔时间等等,参数设置完后调用LocationClient 的setLocOption方法LocationOverlay &MyLocationOverlay的子类,重写里面的dispatchTap()方法,显示弹出窗口图层PopupOverlay,调用mMapView.getOverlays().add(myLocationOverlay)就将我的位置图层添加到地图里面PopupOverlay 弹出图层,这个类还是比较简单,里面只有三个方法,hidePop() (隐藏弹出图层)showPopup(Bitmap pop, GeoPoint point, int yOffset) (显示弹出图层)和showPopup显示多张图片的重载方法,由于showPopup方法只接受Bitmap对象,所以我们必须将我们的弹出图层View对象转换成Bitmap对象,我们调用getBitmapFromView方法就实现这一转换BDLocationListener接口的onReceiveLocation(BDLocation location) 方法我还要重点讲解下,我们会发现onReceiveLocation方法会反复执行,他执行的间隔跟LocationClientOption类的setScanSpan()方法设定的值有关,我们设定的是5000毫秒,则onReceiveLocation方法每隔5秒执行一次,注意,当我们设定的值大于1000(ms),定位SDK内部使用定时定位模式。调用requestLocation( )后,每隔设定的时间,定位SDK就会进行一次定位。如果定位SDK根据定位依据发现位置没有发生变化,就不会发起网络请求,返回上一次定位的结果;如果发现位置改变,就进行网络请求进行定位,得到新的定位结果。如果你只需要定位一次的话,这个设置小于1000,或者不用设置就可以了,定时定位时,调用一次requestLocation,会定时监听到定位结果四 . 在运行程序之前,我们还必须在AndroidManifest.xml进行相关配置和权限的声明在application标签中声明service组件,每个app拥有自己单独的定位service&service
android:name=&com.baidu.location.f&
android:enabled=&true&
android:process=&:remote& &
&/service&声明相关的使用权限
&uses-permission android:name=&android.permission.ACCESS_COARSE_LOCATION& /&
&uses-permission android:name=&android.permission.ACCESS_FINE_LOCATION& /&
&uses-permission android:name=&android.permission.ACCESS_WIFI_STATE& /&
&uses-permission android:name=&android.permission.ACCESS_NETWORK_STATE&/&
&uses-permission android:name=&android.permission.CHANGE_WIFI_STATE& /&
&uses-permission android:name=&android.permission.READ_PHONE_STATE& /&
&uses-permission android:name=&android.permission.WRITE_EXTERNAL_STORAGE& /&
&uses-permission android:name=&android.permission.INTERNET& /&
&uses-permission android:name=&android.permission.MOUNT_UNMOUNT_FILESYSTEMS& /&
&uses-permission android:name=&android.permission.READ_LOGS& /&五 . 运行结果今天的讲解到此结束,有疑问的朋友请在下面留言。之后会持续介绍百度地图的使用,欢迎大家关注!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3844961次
积分:18696
积分:18696
排名:第400名
原创:60篇
转载:15篇
评论:4201条
Android 技术讨论群
我的联系方式
文章:15篇
阅读:631940
(3)(1)(1)(1)(1)(3)(4)(4)(2)(2)(5)(6)(10)(8)(15)(4)(2)(1)(2)

我要回帖

更多关于 检流计指针偏转方向 的文章

 

随机推荐