Android 百度地图开发(二)

这一篇文章主要讲解的是百度地图的定位功能,然后还有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="http://schemas.android.com/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" />  
      
      
     <Button  
         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.baidumapdemo;  
  
import android.app.Activity;  
import android.graphics.Bitmap;  
import android.os.Bundle;  
import android.util.Log;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.View.MeasureSpec;  
import android.view.View.OnClickListener;  
import android.widget.Button;  
import android.widget.TextView;  
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.BMapManager;  
import com.baidu.mapapi.MKGeneralListener;  
import com.baidu.mapapi.map.LocationData;  
import com.baidu.mapapi.map.MKEvent;  
import com.baidu.mapapi.map.MapController;  
import com.baidu.mapapi.map.MapView;  
import com.baidu.mapapi.map.MyLocationOverlay;  
import com.baidu.mapapi.map.PopupClickListener;  
import com.baidu.mapapi.map.PopupOverlay;  
import com.baidu.platform.comapi.basestruct.GeoPoint;  
  
public class MainActivity extends Activity {  
    private Toast mToast;  
    private BMapManager mBMapManager;  
    private MapView mMapView = null;  
    private MapController mMapController = null;  
      
    /** 
     * 定位SDK的核心类 
     */  
    private LocationClient mLocClient;  
    /** 
     * 用户位置信息  
     */  
    private LocationData mLocData;  
    /** 
     * 我的位置图层 
     */  
    private LocationOverlay myLocationOverlay = null;  
    /** 
     * 弹出窗口图层 
     */  
    private PopupOverlay mPopupOverlay  = null;  
      
    private boolean isRequest = false;//是否手动触发请求定位  
    private boolean isFirstLoc = true;//是否首次定位  
      
    /** 
     * 弹出窗口图层的View 
     */  
    private View mPopupView;  
    private BDLocation location;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        //使用地图sdk前需先初始化BMapManager,这个必须在setContentView()先初始化  
        mBMapManager = new BMapManager(this);  
          
        //第一个参数是API key,  
        //第二个参数是常用事件监听,用来处理通常的网络错误,授权验证错误等,你也可以不添加这个回调接口  
        mBMapManager.init("7ae13368159d6a513eaa7a17b9413b4b", new MKGeneralListenerImpl());  
        setContentView(R.layout.activity_main);  
          
        //点击按钮手动请求定位  
        ((Button) findViewById(R.id.request)).setOnClickListener(new OnClickListener() {  
              
            @Override  
            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() {  
              
            /** 
             * 点击弹出窗口图层回调的方法 
             */  
            @Override  
            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类型参数 
         */  
        @Override  
        public void onReceiveLocation(BDLocation location) {  
            if (location == null) {  
                return;  
            }  
              
            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 = 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 = false;  
            }  
            isFirstLoc = false;  
              
        }  
  
        /** 
         * 接收异步返回的POI查询结果,参数是BDLocation类型参数 
         */  
        @Override  
        public void onReceivePoi(BDLocation poiLocation) {  
              
        }  
  
    }  
      
      
  
    //继承MyLocationOverlay重写dispatchTap方法  
    private class LocationOverlay extends MyLocationOverlay{  
  
        public LocationOverlay(MapView arg0) {  
            super(arg0);  
        }  
  
          
        /** 
         * 在“我的位置”坐标上处理点击事件。 
         */  
        @Override  
        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)),  
                    15);  
           
    }  
      
      
    /** 
     * 手动请求定位的方法 
     */  
    public void requestLocation() {  
        isRequest = true;  
          
        if(mLocClient != null && mLocClient.isStarted()){  
            showToast("正在定位......");  
            mLocClient.requestLocation();  
        }else{  
            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);    
        }else{    
            mToast.setText(msg);    
            mToast.setDuration(Toast.LENGTH_SHORT);  
        }    
        mToast.show();    
    }   
      
    /** 
     * 将View转换成Bitmap的方法 
     * @param view 
     * @return 
     */  
    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();  
        return bitmap;  
    }  
      
      
      
      
      
    /** 
     * 常用事件监听,用来处理通常的网络错误,授权验证错误等 
     * @author xiaanming 
     * 
     */  
    public class MKGeneralListenerImpl implements MKGeneralListener{  
  
        /** 
         * 一些网络状态的错误处理回调函数 
         */  
        @Override  
        public void onGetNetworkState(int iError) {  
            if (iError == MKEvent.ERROR_NETWORK_CONNECT) {  
                showToast("您的网络出错啦!");  
            }  
        }  
  
        /** 
         * 授权错误的时候调用的回调函数 
         */  
        @Override  
        public void onGetPermissionState(int iError) {  
            if (iError ==  MKEvent.ERROR_PERMISSION_DENIED) {  
                showToast("API KEY错误, 请检查!");  
            }  
        }  
          
    }  
      
    @Override  
    protected void onResume() {  
        //MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()  
        mMapView.onResume();  
        super.onResume();  
    }  
  
  
  
    @Override  
    protected void onPause() {  
        //MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()  
        mMapView.onPause();  
        super.onPause();  
    }  
  
    @Override  
    protected void onDestroy() {  
        //MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()  
        mMapView.destroy();  
          
        //退出应用调用BMapManager的destroy()方法  
        if(mBMapManager != null){  
            mBMapManager.destroy();  
            mBMapManager = null;  
        }  
          
        //退出时销毁定位  
        if (mLocClient != null){  
            mLocClient.stop();  
        }  
          
        super.onDestroy();  
    }           
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值