百度地图之定位

百度地图之定位功能

配置开发环境

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值