您的位置:首页 > 移动开发 > Android开发

百度地图之定位

2016-04-25 20:59 591 查看


百度地图之定位功能

配置开发环境

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

1. 导入库文件。

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

2. 添加定位service

[html] view
plain copy

 





<service  

        android:name="com.baidu.location.f"  

        android:enabled="true"  

        android:process=":remote" >  

</service>  

3. 添加权限

[html] view
plain copy

 





<!-- 这个权限用于进行网络定位 -->  

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >  

    </uses-permission>  

    <!-- 这个权限用于访问GPS定位 -->  

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >  

    </uses-permission>  

    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->  

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >  

    </uses-permission>  

    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->  

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >  

    </uses-permission>  

    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->  

    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >  

    </uses-permission>  

    <!-- 用于读取手机当前的状态 -->  

    <uses-permission android:name="android.permission.READ_PHONE_STATE" >  

    </uses-permission>  

    <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据 -->  

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >  

    </uses-permission>  

    <!-- 访问网络,网络定位需要上网 -->  

    <uses-permission android:name="android.permission.INTERNET" />  

    <!-- SD卡读取权限,用户写入离线定位数据 -->  

    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >  

    </uses-permission>  

    <!-- 允许应用读取低级别的系统日志文件 -->  

    <uses-permission android:name="android.permission.READ_LOGS" >  

    </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

 





LocationClientOption locOption = new LocationClientOption();  

        locOption.setLocationMode(LocationMode.Hight_Accuracy);// 设置定位模式  

        locOption.setCoorType("bd09ll");// 设置定位结果类型  

        locOption.setScanSpan(5000);// 设置发起定位请求的间隔时间,ms。少于1000ms,定位无效

        locOption.setIsNeedAddress(true);// 返回的定位结果包含地址信息、默认不需要地址  

        locOption.setNeedDeviceDirect(true);// 设置返回结果包含手机的方向    

locOption.setOPenGps(true)//打开GPS

        locationClient.setLocOption(locOption);  

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



    设置请求定位时间间隔:



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



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



(3)设置定位监听函数

locationClient.registerLocationListener(locationListener);  

[java] view
plain copy

 





//创建监听类

class MyLocationListener implements BDLocationListener {  

        // 异步返回的定位结果  

        @Override  

        public void onReceiveLocation(BDLocation location) {  

    }  

}  

    百度官网说明有一些是不准确的。实现BDLocationListener接口的时候,在之前的版本是有两个方法需要实现,新版本(5.0)的只有一个方法需要实现:onReceiveLocation()。BDLocation类封装了定位SDK的定位结果,通过该可以获取定位返回的结果、位置坐标、精度半径等信息。





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



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

[java] view
plain copy

 





} else if (locType == BDLocation.TypeNetWorkLocation) {  

                addrStr = location.getAddrStr();// 获取反地理编码(文字描述的地址)  

                Toast.makeText(LocationActivity.this, addrStr,  

                        Toast.LENGTH_SHORT).show();  

            }  

    (4)添加位置提醒监听函数

[java] view
plain copy

 





notifyListener = new MyNotifyListener();  

notifyListener.SetNotifyLocation(longitude, latitude, 3000, "bd09ll");//精度,维度,范围,坐标类型  

locationClient.registerNotify(notifyListener);  

[java] view
plain copy

 





/** 

     * 位置提醒监听器 

     * @author ys 

     * 

     */  

    class MyNotifyListener extends BDNotifyListener {  

        @Override  

        public void onNotify(BDLocation bdLocation, float distance) {  

            super.onNotify(bdLocation, distance);  

            mVibrator.vibrate(1000);//振动提醒已到设定位置附近  

            Toast.makeText(LocationActivity.this, "震动提醒", Toast.LENGTH_SHORT).show();  

        }  

    }  

    (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

 





@Override  

    protected void onDestroy() {  

        super.onDestroy();  

        mapview.onDestroy();  

        locationClient.unRegisterLocationListener(locationListener);  

        //取消位置提醒  

        locationClient.removeNotifyEvent(notifyListener);  

        locationClient.stop();  

    }  

    此时可以完成了一个基本的地图定位功能和位置提醒。如果要显示在地图上,就想百度那样出现一个点表示地图的定位点,就需要用到MyLocationConfiguration(配置定位图层显示方式)和MylocationData(定位数据)。

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

[java] view
plain copy

 





// 构造定位数据  

            MyLocationData locData = new MyLocationData.Builder()  

                    .accuracy(radius)//  

                    .direction(direction)// 方向  

                    .latitude(latitude)//  

                    .longitude(longitude)//  

                    .build();  

            // 设置定位数据  

            bdMap.setMyLocationData(locData);  

    通过定位的onReceiveLocation()方法可以得到定位的经纬度,然后可以通过animationMapStatus()方法把定位到的点移动到地图中心。

[java] view
plain copy

 





LatLng ll = new LatLng(latitude, longitude);  

            MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(ll);  

            bdMap.animateMapStatus(msu);  

    定位图层的显示方式有三种:普通、跟随、罗盘,在MyLocationConfiguration.LocationMode这个内部类中定义为枚举常量。



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



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



[java] view
plain copy

 





switch (currentMode) {  

            case NORMAL:  

                locateBtn.setText("跟随");  

                currentMode = MyLocationConfiguration.LocationMode.FOLLOWING;  

                break;  

            case FOLLOWING:  

                locateBtn.setText("罗盘");  

                currentMode = MyLocationConfiguration.LocationMode.COMPASS;  

                break;  

            case COMPASS:  

                locateBtn.setText("普通");  

                currentMode = MyLocationConfiguration.LocationMode.NORMAL;  

                break;  

            }  

            bdMap.setMyLocationConfigeration(new MyLocationConfiguration(  

                    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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息