百度地图之定位

来源:互联网 发布:无名的裘德 知乎 编辑:程序博客网 时间:2024/05/16 17:40

百度地图之定位功能

配置开发环境

在下面的blog里有已经配置好环境的AS项目,可以下载使用:
已经配置好环境的demo

1. 导入库文件。

    下载下来lib压缩包之后,会看到很多文件夹(有jar 包和so文件),官方建议:eclipse全部拷贝到lib下,AS把so文件放入新建jniLibs文件夹中。具体可参照 百度地图开发环境配置详情
2. 添加定位service

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <service  
  2.         android:name="com.baidu.location.f"  
  3.         android:enabled="true"  
  4.         android:process=":remote" >  
  5. </service>  
3. 添加权限

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <!-- 这个权限用于进行网络定位 -->  
  2.     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >  
  3.     </uses-permission>  
  4.     <!-- 这个权限用于访问GPS定位 -->  
  5.     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >  
  6.     </uses-permission>  
  7.     <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->  
  8.     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >  
  9.     </uses-permission>  
  10.     <!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->  
  11.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >  
  12.     </uses-permission>  
  13.     <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->  
  14.     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >  
  15.     </uses-permission>  
  16.     <!-- 用于读取手机当前的状态 -->  
  17.     <uses-permission android:name="android.permission.READ_PHONE_STATE" >  
  18.     </uses-permission>  
  19.     <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据 -->  
  20.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >  
  21.     </uses-permission>  
  22.     <!-- 访问网络,网络定位需要上网 -->  
  23.     <uses-permission android:name="android.permission.INTERNET" />  
  24.     <!-- SD卡读取权限,用户写入离线定位数据 -->  
  25.     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >  
  26.     </uses-permission>  
  27.     <!-- 允许应用读取低级别的系统日志文件 -->  
  28.     <uses-permission android:name="android.permission.READ_LOGS" >  
  29.     </uses-permission>  
4. 编写定位程序
    百度地图可以使用GPS和网络定位(WIFI和基站)进行定位。基本定位功能还支持定位结果的反地理编码功能,离线定位,位置提醒功能和地理围栏功能。

主要会用到的类:

LocationClient、BDLocationListener、BDNotifyListener、LocationClientOption


主要会用到该类中的以下几个方法:

官方API参照地址:

百度地图官方API参照地址






(2)设置定位参数:

    主要的参数有:定位模式、返回坐标类型、是否打开GPS等。

定位模式分为三种:

1. 高精度定位模式:同时使用网络定位和GPS定位,优先返回最高精度的定位结果。

2. 低功耗定位模式:不使用GPS,只使用网络定位(WiFi和基站)。

3. 仅用设备定位模式: 不适用网络定位,只使用GPS进行定位。但是此模式下不支持室内环境的定位。


    在API中主要关注“setxxx”类型的函数。主要用到红色框标注的方法。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. LocationClientOption locOption = new LocationClientOption();  
  2.         locOption.setLocationMode(LocationMode.Hight_Accuracy);// 设置定位模式  
  3.         locOption.setCoorType("bd09ll");// 设置定位结果类型  
  4.         locOption.setScanSpan(5000);// 设置发起定位请求的间隔时间,ms。少于1000ms,定位无效
  5.         locOption.setIsNeedAddress(true);// 返回的定位结果包含地址信息、默认不需要地址  
  6.         locOption.setNeedDeviceDirect(true);// 设置返回结果包含手机的方向    
  7. locOption.setOPenGps(true)//打开GPS

  8.         locationClient.setLocOption(locOption);  
    坐标类型分为三种:国测局经纬度坐标系(gcj02),百度墨卡托坐标系(bd09),百度经纬度坐标系(bd09ll)。


    设置请求定位时间间隔:


    设置返回结果包含地址信息:


    设置返回结果中包含手机方向:


(3)设置定位监听函数

locationClient.registerLocationListener(locationListener);  

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //创建监听类
  2. class MyLocationListener implements BDLocationListener {  
  3.         // 异步返回的定位结果  
  4.         @Override  
  5.         public void onReceiveLocation(BDLocation location) {  
  6.     }  
  7. }  
    百度官网说明有一些是不准确的。实现BDLocationListener接口的时候,在之前的版本是有两个方法需要实现,新版本(5.0)的只有一个方法需要实现:onReceiveLocation()。BDLocation类封装了定位SDK的定位结果,通过该可以获取定位返回的结果、位置坐标、精度半径等信息。



    定位成功与否,定位的错误码都是通过getLocType()这个方法得到的,返回值是int类型。


    注意:只有在使用网络定位的情况下,才能获取当前位置的反地理编码。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. else if (locType == BDLocation.TypeNetWorkLocation) {  
  2.                 addrStr = location.getAddrStr();// 获取反地理编码(文字描述的地址)  
  3.                 Toast.makeText(LocationActivity.this, addrStr,  
  4.                         Toast.LENGTH_SHORT).show();  
  5.             }  
    (4)添加位置提醒监听函数

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. notifyListener = new MyNotifyListener();  
  2. notifyListener.SetNotifyLocation(longitude, latitude, 3000"bd09ll");//精度,维度,范围,坐标类型  
  3. locationClient.registerNotify(notifyListener);  

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.      * 位置提醒监听器 
  3.      * @author ys 
  4.      * 
  5.      */  
  6.     class MyNotifyListener extends BDNotifyListener {  
  7.         @Override  
  8.         public void onNotify(BDLocation bdLocation, float distance) {  
  9.             super.onNotify(bdLocation, distance);  
  10.             mVibrator.vibrate(1000);//振动提醒已到设定位置附近  
  11.             Toast.makeText(LocationActivity.this"震动提醒", Toast.LENGTH_SHORT).show();  
  12.         }  
  13.     }  
    (5)开启定位
    LocationClient的start()方法用来启动定位SDK,requestLocation()方法用来请求一次定位,请求过程是异步的。调用start()方法之后,会根据你设置的定位事件间隔来请求定位。

 @Override    protected void onStart() {        super.onStart();        //开启定位        mBaiduMap.setMyLocationEnabled(true);        if (!myLocate.mLocationClient.isStarted()) {            myLocate.mLocationClient.start();        }    }

    (6)最后不要忘了在不用的时候注销定位监听和位置提醒监听,并且关闭地图。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2.     protected void onDestroy() {  
  3.         super.onDestroy();  
  4.         mapview.onDestroy();  
  5.         locationClient.unRegisterLocationListener(locationListener);  
  6.         //取消位置提醒  
  7.         locationClient.removeNotifyEvent(notifyListener);  
  8.         locationClient.stop();  
  9.     }  
    此时可以完成了一个基本的地图定位功能和位置提醒。如果要显示在地图上,就想百度那样出现一个点表示地图的定位点,就需要用到MyLocationConfiguration(配置定位图层显示方式)MylocationData(定位数据)

    MyLocationData包含一个内部了Builder用于构建MyLocationData对象:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. // 构造定位数据  
  2.             MyLocationData locData = new MyLocationData.Builder()  
  3.                     .accuracy(radius)//  
  4.                     .direction(direction)// 方向  
  5.                     .latitude(latitude)//  
  6.                     .longitude(longitude)//  
  7.                     .build();  
  8.             // 设置定位数据  
  9.             bdMap.setMyLocationData(locData);  
    通过定位的onReceiveLocation()方法可以得到定位的经纬度,然后可以通过animationMapStatus()方法把定位到的点移动到地图中心。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. LatLng ll = new LatLng(latitude, longitude);  
  2.             MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(ll);  
  3.             bdMap.animateMapStatus(msu);  
    定位图层的显示方式有三种:普通、跟随、罗盘,在MyLocationConfiguration.LocationMode这个内部类中定义为枚举常量。

    我们来看一下MyLocationConfiguration的构造函数:


    第一个参数就是图层的显示方式(LocationMode类型),第二个参数表示是否显示方向信息(booleab类型),第三个参数是(bitmapDescriptor类型,我们在前面的blog有过介绍了)。构造出这个对象之后,就可以调用BaiduMap的setMyLocationConfigeration()方法来设置定位图层配置信息了。


[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. switch (currentMode) {  
  2.             case NORMAL:  
  3.                 locateBtn.setText("跟随");  
  4.                 currentMode = MyLocationConfiguration.LocationMode.FOLLOWING;  
  5.                 break;  
  6.             case FOLLOWING:  
  7.                 locateBtn.setText("罗盘");  
  8.                 currentMode = MyLocationConfiguration.LocationMode.COMPASS;  
  9.                 break;  
  10.             case COMPASS:  
  11.                 locateBtn.setText("普通");  
  12.                 currentMode = MyLocationConfiguration.LocationMode.NORMAL;  
  13.                 break;  
  14.             }  
  15.             bdMap.setMyLocationConfigeration(new MyLocationConfiguration(  
  16.                     currentMode, true, currentMarker));  


自定义的Locate(定位)类:

该代码需要外部传入调用者的Context 和 一个BaiduMap实例

想要运行还需要同上面第五点所说那样,在MainActivity 的start()方法中去开启定位功能

 protected void onStart() {        super.onStart();        //开启定位        mBaiduMap.setMyLocationEnabled(true);        if (!myLocate.mLocationClient.isStarted()) {            myLocate.mLocationClient.start();        }    }

实现代码如下:

import android.content.Context;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.map.BaiduMap;import com.baidu.mapapi.map.BitmapDescriptorFactory;import com.baidu.mapapi.map.MapStatusUpdate;import com.baidu.mapapi.map.MapStatusUpdateFactory;import com.baidu.mapapi.map.MyLocationConfiguration;import com.baidu.mapapi.map.MyLocationData;import com.baidu.mapapi.model.LatLng;import utils.MyLog;/** * Created by Adminis on 2016/5/28. */public class Locate {    /**     *  内部生成的参数:     *   mLatitue经度 ,mLongLatitue纬度     *   mLocationClient 定位类     *   mLocationListener 与定位相关的接口     *     *  外部传入的参数:     *  mBaiduMap 、 context     *     *     *    * */    private BaiduMap mBaiduMap;    private Context context;    private double mLatitue;    private double mLongLatitue;    // 当前位置的详细信息    private String myAddress;    //判断是否是第一次进入应用    boolean isFirstIn = true;    //MainActivity中用到过,mLocationClient,用来打开和关闭mLocationClient    LocationClient mLocationClient;    MyLocationListener mLocationListener;    public Locate(Context context, BaiduMap mBaiduMap) {        this.context = context;        this.mBaiduMap = mBaiduMap;        MyLog.LogE("Locate", "Locate");    }         /**           * LocationClient类是定位SDK的核心类,           * 必须在主线程中声明。           * 需要传入一个Context类型的参数,           * 推荐使用getApplicationContext()来获取全局进程有效的context。           * */    public void initLocation() {        MyLog.LogE("Locate", "initLocation");        mLocationClient = new LocationClient(context);        mLocationListener = new MyLocationListener();        //接口注册        mLocationClient.registerLocationListener(mLocationListener);        //定位相关的设置        LocationClientOption option = new LocationClientOption();        //  坐标类型分为三种:国测局经纬度坐标系(gcj02),百度墨卡托坐标系(bd09),百度经纬度坐标系(bd09ll)。        option.setCoorType("bd09ll");//设置坐标类型        option.setIsNeedAddress(true);//默认不需要地址,返回的定位结果包含地址信息        option.setOpenGps(true);//打开GPS        option.setScanSpan(1000);//扫描时间,小于1000时,定位无效        option.setNeedDeviceDirect(true);// 设置返回结果包含手机的方向        mLocationClient.setLocOption(option);    }    private class MyLocationListener implements BDLocationListener {        @Override        public void onReceiveLocation(BDLocation location) {            MyLog.LogE("Locate", "onReceiveLocation");            /**             *  如果要显示在地图上,就想百度那样出现一个点表示地图的定位点,             *  就需要用到MyLocationConfiguration(配置定位图层显示方式)             *  和 MylocationData(定位数据)。             */            //建造者模式            MyLocationData data = new MyLocationData.Builder()                    .accuracy(location.getRadius())//                    .direction(location.getDirection())                    .latitude(location.getLatitude())                    .longitude(location.getLongitude())                    .build();            mBaiduMap.setMyLocationData(data);            /**            *    用来显示状态和标志            *      定位图层的显示方式:             *     有三种(跟踪、罗盘、和普通模式            *     MyLocationConfiguration.LocationMode.COMPASS            *     MyLocationConfiguration.LocationMode.FOLLOWING            *     MyLocationConfiguration.LocationMode.NORMAL )            * */            MyLocationConfiguration configuration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.COMPASS                    , true, BitmapDescriptorFactory.fromResource(R.drawable.icon_car));            mBaiduMap.setMyLocationConfigeration(configuration);            // 得到当前位置信息            myAddress = location.getAddrStr();            MyLog.LogE("mLatitue", mLatitue + "location.getAddress();");            // 时时获取经纬度            mLatitue = location.getLatitude();            mLongLatitue = location.getLongitude();            MyLog.LogE("mLatitue", mLatitue + "");            MyLog.LogE("mLongLatitue", mLongLatitue + "");            //判断是否是第一次进入应用            if (isFirstIn) {                centerToMyLocation();            }        }    }    public void centerToMyLocation() {        //定位功能        LatLng latLng = new LatLng(mLatitue, mLongLatitue);        //地图状态将要发生的变化        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);        //设置地图中心点        mBaiduMap.animateMapStatus(msu);        isFirstIn = false;        if (myAddress != null) {            Toast.makeText(context, myAddress, Toast.LENGTH_SHORT).show();            MainActivity.t.speak("当前位置"+myAddress);        }    }    public double getmLatitue() {        return mLatitue;    }    public double getmLongLatitue() {        return mLongLatitue;    }}


参考:

http://blog.csdn.net/crazy1235/article/details/43898451

0 0
原创粉丝点击