第三方SDK:百度地图(二)定位 + 鹰眼轨迹

#1 基础地图 + 基础定位#
可以看到地图的界面。

如图:

第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第1张图片

"http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.cqc.baidumapdemo02.MainActivity" >

    <item
        android:id="@+id/menu_normal"
        android:showAsAction="never"
        android:title="普通图"/>
    <item
        android:id="@+id/menu_satellite"
        android:showAsAction="never"
        android:title="卫星图"/>
    <item
        android:id="@+id/menu_none"
        android:showAsAction="never"
        android:title="空白图"/>
    <item
        android:id="@+id/menu_traffic"
        android:showAsAction="never"
        android:title="交通图"/>
    <item
        android:id="@+id/menu_mylocation"
        android:showAsAction="never"
        android:title="定位我的位置"/>
    <item
        android:id="@+id/menu_location_normal"
        android:showAsAction="never"
        android:title="普通模式"/>
    <item
        android:id="@+id/menu_location_follow"
        android:showAsAction="never"
        android:title="跟随模式"/>
    <item
        android:id="@+id/menu_location_compass"
        android:showAsAction="never"
        android:title="罗盘模式"/>

MainActivity.java

package com.imooc.baidumap;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
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.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnMapClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.InfoWindow.OnInfoWindowClickListener;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.imooc.baidumap.MyOrientationListener.OnOrientationListener;

public class MainActivity extends Activity
{
    private MapView mMapView;
    private BaiduMap mBaiduMap;

    private Context context;

    // 定位相关
    private LocationClient mLocationClient;
    private MyLocationListener mLocationListener;
    private boolean isFirstIn = true;
    private double mLatitude;
    private double mLongtitude;
    // 自定义定位图标
    private BitmapDescriptor mIconLocation;
    private MyOrientationListener myOrientationListener;
    private float mCurrentX;
    private LocationMode mLocationMode;

    // 覆盖物相关
    private BitmapDescriptor mMarker;
    private RelativeLayout mMarkerLy;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        // requestWindowFeature(Window.FEATURE_NO_TITLE);
        // 在使用SDK各组件之前初始化context信息,传入ApplicationContext
        // 注意该方法要再setContentView方法之前实现
//      getWindow().setFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY,
//              WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);

        this.context = this;

        initView();
        // 初始化定位
        initLocation();
        initMarker();

        mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener()
        {
            @Override
            public boolean onMarkerClick(Marker marker)
            {
                Bundle extraInfo = marker.getExtraInfo();
                Info info = (Info) extraInfo.getSerializable("info");
                ImageView iv = (ImageView) mMarkerLy
                        .findViewById(R.id.id_info_img);
                TextView distance = (TextView) mMarkerLy
                        .findViewById(R.id.id_info_distance);
                TextView name = (TextView) mMarkerLy
                        .findViewById(R.id.id_info_name);
                TextView zan = (TextView) mMarkerLy
                        .findViewById(R.id.id_info_zan);
                iv.setImageResource(info.getImgId());
                distance.setText(info.getDistance());
                name.setText(info.getName());
                zan.setText(info.getZan() + "");

                InfoWindow infoWindow;
                TextView tv = new TextView(context);
                tv.setBackgroundResource(R.drawable.location_tips);
                tv.setPadding(30, 20, 30, 50);
                tv.setText(info.getName());
                tv.setTextColor(Color.parseColor("#ffffff"));

                final LatLng latLng = marker.getPosition();
                Point p = mBaiduMap.getProjection().toScreenLocation(latLng);
                p.y -= 47;
                LatLng ll = mBaiduMap.getProjection().fromScreenLocation(p);

                infoWindow = new InfoWindow(tv, ll,
                        new OnInfoWindowClickListener()
                        {
                            @Override
                            public void onInfoWindowClick()
                            {
                                mBaiduMap.hideInfoWindow();
                            }
                        });
                mBaiduMap.showInfoWindow(infoWindow);
                mMarkerLy.setVisibility(View.VISIBLE);
                return true;
            }
        });
        mBaiduMap.setOnMapClickListener(new OnMapClickListener()
        {

            @Override
            public boolean onMapPoiClick(MapPoi arg0)
            {
                return false;
            }

            @Override
            public void onMapClick(LatLng arg0)
            {
                mMarkerLy.setVisibility(View.GONE);
                mBaiduMap.hideInfoWindow();
            }
        });
    }

    private void initMarker()
    {
        mMarker = BitmapDescriptorFactory.fromResource(R.drawable.maker);
        mMarkerLy = (RelativeLayout) findViewById(R.id.id_maker_ly);
    }

    private void initLocation()
    {

        mLocationMode = LocationMode.NORMAL;
        mLocationClient = new LocationClient(this);
        mLocationListener = new MyLocationListener();
        mLocationClient.registerLocationListener(mLocationListener);

        LocationClientOption option = new LocationClientOption();
        option.setCoorType("bd09ll");
        option.setIsNeedAddress(true);
        option.setOpenGps(true);
        option.setScanSpan(1000);
        mLocationClient.setLocOption(option);
        // 初始化图标
        mIconLocation = BitmapDescriptorFactory
                .fromResource(R.drawable.navi_map_gps_locked);
        myOrientationListener = new MyOrientationListener(context);

        myOrientationListener
                .setOnOrientationListener(new OnOrientationListener()
                {
                    @Override
                    public void onOrientationChanged(float x)
                    {
                        mCurrentX = x;
                    }
                });

    }

    private void initView()
    {
        mMapView = (MapView) findViewById(R.id.id_bmapView);
        mBaiduMap = mMapView.getMap();
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);
        mBaiduMap.setMapStatus(msu);
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        // 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mMapView.onResume();
    }

    @Override
    protected void onStart()
    {
        super.onStart();
        // 开启定位
        mBaiduMap.setMyLocationEnabled(true);
        if (!mLocationClient.isStarted())
            mLocationClient.start();
        // 开启方向传感器
        myOrientationListener.start();
    }

    @Override
    protected void onPause()
    {
        super.onPause();
        // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mMapView.onPause();
    }

    @Override
    protected void onStop()
    {
        super.onStop();

        // 停止定位
        mBaiduMap.setMyLocationEnabled(false);
        mLocationClient.stop();
        // 停止方向传感器
        myOrientationListener.stop();

    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mMapView.onDestroy();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId())
        {
        case R.id.id_map_common:
            mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
            break;

        case R.id.id_map_site:
            mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
            break;

        case R.id.id_map_traffic:
            if (mBaiduMap.isTrafficEnabled())
            {
                mBaiduMap.setTrafficEnabled(false);
                item.setTitle("实时交通(off)");
            } else
            {
                mBaiduMap.setTrafficEnabled(true);
                item.setTitle("实时交通(on)");
            }
            break;
        case R.id.id_map_location:
            centerToMyLocation();
            break;
        case R.id.id_map_mode_common:
            mLocationMode = LocationMode.NORMAL;
            break;
        case R.id.id_map_mode_following:
            mLocationMode = LocationMode.FOLLOWING;
            break;
        case R.id.id_map_mode_compass:
            mLocationMode = LocationMode.COMPASS;
            break;
        case R.id.id_add_overlay:
            addOverlays(Info.infos);
            break;
        default:
            break;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * 添加覆盖物
     * 
     * @param infos
     */
    private void addOverlays(List infos)
    {
        mBaiduMap.clear();
        LatLng latLng = null;
        Marker marker = null;
        OverlayOptions options;
        for (Info info : infos)
        {
            // 经纬度
            latLng = new LatLng(info.getLatitude(), info.getLongitude());
            // 图标
            options = new MarkerOptions().position(latLng).icon(mMarker)
                    .zIndex(5);
            marker = (Marker) mBaiduMap.addOverlay(options);
            Bundle arg0 = new Bundle();
            arg0.putSerializable("info", info);
            marker.setExtraInfo(arg0);
        }

        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
        mBaiduMap.setMapStatus(msu);

    }

    /**
     * 定位到我的位置
     */
    private void centerToMyLocation()
    {
        LatLng latLng = new LatLng(mLatitude, mLongtitude);
        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
        mBaiduMap.animateMapStatus(msu);
    }

    private class MyLocationListener implements BDLocationListener
    {
        @Override
        public void onReceiveLocation(BDLocation location)
        {

            MyLocationData data = new MyLocationData.Builder()//
                    .direction(mCurrentX)//
                    .accuracy(location.getRadius())//
                    .latitude(location.getLatitude())//
                    .longitude(location.getLongitude())//
                    .build();
            mBaiduMap.setMyLocationData(data);
            // 设置自定义图标
            MyLocationConfiguration config = new MyLocationConfiguration(
                    mLocationMode, true, mIconLocation);
            mBaiduMap.setMyLocationConfigeration(config);

            // 更新经纬度
            mLatitude = location.getLatitude();
            mLongtitude = location.getLongitude();

            if (isFirstIn)
            {
                LatLng latLng = new LatLng(location.getLatitude(),
                        location.getLongitude());
                MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
                mBaiduMap.animateMapStatus(msu);
                isFirstIn = false;

                Toast.makeText(context, location.getAddrStr(),
                        Toast.LENGTH_SHORT).show();
            }

        }
    }

}

2 只使用基础定位

copy 基础定位 文档即可。http://lbsyun.baidu.com/index.php?title=android-locsdk
注意:只是实现基础定位功能,是不需要在application中声明context的!!!!

步骤:

1 获取密钥:key
2 环境配置
3 获取位置
     1 创建LocationClient 和 BDLocationListener对象
     2 给LocationClient 对象设置参数,和注册监听
     3 开启定位

1 获取密钥:key

这个再讲了,见百度地图(一):HelloBaiDuMap,或者官方文档:http://lbsyun.baidu.com/index.php?title=androidsdk/guide/key

2 环境配置

步骤:

1 先下载基础定位SDK
2 配置jar+so文件
3 配置AndoridManifest.xml(网络权限 + 定位service + 定位key)

先下载基础定位:

只需要下载这一个即可,不需要其他的,不需要基础地图(这次只定位,不看图)

第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第2张图片

配置jar+so文件

将jar文件放入libs文件夹中,在project结构中,src/main下创建jniLibs文件夹,将各架构下的so文件放入其中。见下图:

第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第3张图片

配置AndoridManifest.xml(网络权限 + 定位service + 定位key)

网络权限:


    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION">uses-permission>
    
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">uses-permission>
    
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE">uses-permission>
    
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">uses-permission>
    
    <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"/>
    
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS">uses-permission>

声明定位service:


 <service
     android:name="com.baidu.location.f"
     android:enabled="true"
     android:process=":remote">
 service>

有的版本指定service,所以要看清下载的sdk+demo,最好复制demo的

<service
    android:name="com.baidu.location.f"
    android:enabled="true"
    android:process=":remote">
    <intent-filter>
        <action android:name="com.baidu.location.service_v2.2">
        action>
    intent-filter>
service>

定位key:

 
 <meta-data
     android:name="com.baidu.lbsapi.API_KEY"
     android:value="tpiB1a5OmkkFz4ZYSRyByp9bqHYjML4D"/>

3 获取位置

步骤:

1 创建LocationClient对象
2 设置参数
3 设置监听(可以在监听中获取地址)

创建LocationClient对象

mLocationClient = new LocationClient(getApplicationContext());     //声明LocationClient类

设置参数

 private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
        option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系
        int span = 0;
        option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
        option.setOpenGps(true);//可选,默认false,设置是否使用gps
        option.setLocationNotify(true);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
        option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
        option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
        option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要
        mLocationClient.setLocOption(option);
    }

设置监听(可以在监听中获取地址)

    public class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            //Receive Location
            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) {// GPS定位结果
                sb.append("\nspeed : ");
                sb.append(location.getSpeed());// 单位:公里每小时
                sb.append("\nsatellite : ");
                sb.append(location.getSatelliteNumber());
                sb.append("\nheight : ");
                sb.append(location.getAltitude());// 单位:米
                sb.append("\ndirection : ");
                sb.append(location.getDirection());// 单位度
                sb.append("\naddr : ");
                sb.append(location.getAddrStr());
                sb.append("\ndescribe : ");
                sb.append("gps定位成功");

            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
                sb.append("\naddr : ");
                sb.append(location.getAddrStr());
                //运营商信息
                sb.append("\noperationers : ");
                sb.append(location.getOperators());
                sb.append("\ndescribe : ");
                sb.append("网络定位成功");
            } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
                sb.append("\ndescribe : ");
                sb.append("离线定位成功,离线定位结果也是有效的");
            } else if (location.getLocType() == BDLocation.TypeServerError) {
                sb.append("\ndescribe : ");
                sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到[email protected],会有人追查原因");
            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                sb.append("\ndescribe : ");
                sb.append("网络不同导致定位失败,请检查网络是否通畅");
            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                sb.append("\ndescribe : ");
                sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
            }
            sb.append("\nlocationdescribe : ");
            sb.append(location.getLocationDescribe());// 位置语义化信息
            List list = location.getPoiList();// POI数据
            if (list != null) {
                sb.append("\npoilist size = : ");
                sb.append(list.size());
                for (Poi p : list) {
                    sb.append("\npoi= : ");
                    sb.append(p.getId() + " " + p.getName() + " " + p.getRank());
                }
            }
            //获取定位信息
            Log.i("BaiduLocationApiDem", sb.toString());
            //获取位置信息
            Log.i("BaiduLocationApiDem", location.getAddrStr());
        }
    }

开启定位

mLocationClient = new LocationClient(getApplicationContext());     //声明LocationClient类
mLocationClient.registerLocationListener(myListener);    //注册监听函数
initLocation();//设置参数
mLocationClient.start();

没有调用initLocation()方法时,打印的log为:
第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第4张图片
调用initLocation()方法时,打印的log为:
第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第5张图片

注意:按照百度基本定位SDK文档说明,定位用的一个API_key是不可以对应多个包名的,但我在实际测试中发现定位的一个key,可以对应多个包名(各位可以尝试修改本demo的applicationId,会发现log仍然有地址)。但是仅限定位,基本地图就不可以。

源码:

源码下载:https://github.com/s1168805219/jichudingwei

每隔10秒定位一次,并获取定位信息

只是多了一个条件:“每隔10秒定位一次”,这次放在了service中,其他都一样.下图是每隔10秒的定位数据,10秒有点短,但基本获取到了数据,也基本是间隔10秒。

第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第6张图片

public class LocationService extends Service {

    private int seconds = 10;
    public LocationClient mLocationClient = null;
    public BDLocationListener myListener = new MyLocationListener();
    private Timer timer;
    private TimerTask mTask;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mLocationClient = new LocationClient(LocationService.this);     //声明LocationClient类
        mLocationClient.registerLocationListener(myListener);    //注册监听函数
        initLocation();//设置参数
        mLocationClient.start();
        //以上代码是copy官网文档

        //设置1秒后,每个seconds秒定位一次,定位信息log中有打印
        timer = new Timer();
        timer.schedule(task, 1000,seconds * 1000);//1秒后,每个seconds秒定位一次。
    }

    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            mLocationClient.start();
            mLocationClient.requestLocation();
        }
    };

    @Override
    public void onDestroy() {
        super.onDestroy();
        timer.cancel();
        mLocationClient.unRegisterLocationListener(myListener);
    }


    //这个方法是copy官网文档
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
        option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系
        int span = 0;
        option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
        option.setOpenGps(true);//可选,默认false,设置是否使用gps
        option.setLocationNotify(true);//可选,默认false,设置是否当GPS有效时按照1S/1次频率输出GPS结果
        option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
        option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
        option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤GPS仿真结果,默认需要
        mLocationClient.setLocOption(option);
    }

    public class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            //Receive Location
            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) {// GPS定位结果
                sb.append("\nspeed : ");
                sb.append(location.getSpeed());// 单位:公里每小时
                sb.append("\nsatellite : ");
                sb.append(location.getSatelliteNumber());
                sb.append("\nheight : ");
                sb.append(location.getAltitude());// 单位:米
                sb.append("\ndirection : ");
                sb.append(location.getDirection());// 单位度
                sb.append("\naddr : ");
                sb.append(location.getAddrStr());
                sb.append("\ndescribe : ");
                sb.append("gps定位成功");

            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
                sb.append("\naddr : ");
                sb.append(location.getAddrStr());
                //运营商信息
                sb.append("\noperationers : ");
                sb.append(location.getOperators());
                sb.append("\ndescribe : ");
                sb.append("网络定位成功");
            } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
                sb.append("\ndescribe : ");
                sb.append("离线定位成功,离线定位结果也是有效的");
            } else if (location.getLocType() == BDLocation.TypeServerError) {
                sb.append("\ndescribe : ");
                sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到[email protected],会有人追查原因");
            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                sb.append("\ndescribe : ");
                sb.append("网络不同导致定位失败,请检查网络是否通畅");
            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                sb.append("\ndescribe : ");
                sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
            }
            sb.append("\nlocationdescribe : ");
            sb.append(location.getLocationDescribe());// 位置语义化信息
            List list = location.getPoiList();// POI数据
            if (list != null) {
                sb.append("\npoilist size = : ");
                sb.append(list.size());
                for (Poi p : list) {
                    sb.append("\npoi= : ");
                    sb.append(p.getId() + " " + p.getName() + " " + p.getRank());
                }
            }
//            Log.i("BaiduLocationApiDem", sb.toString());

            //以上代码是copy官网文档
            mLocationClient.stop();
            Log.i("BaiduLocationApiDem", "LocationService--" + location.getAddrStr() + "errorCode=" + location.getLocType());
        }
    }
}

源码:https://git.oschina.net/BaiDuMapSDK/DingWei03

prodName

第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第7张图片

相关博文

重拾百度定位之踩坑篇

定位问题

开手机热点:,请求不到我们的服务器(刷新没有返回运单信息),应该是网络不行,也就无法发送坐标。

经纬度是0:表示没有获取到经纬度坐标,默认值都是:Double.MIN_VALUE,也就是0
可能是没开GPS,也可能是没给位置权限

GPS定位的情况下会出现这种情况:有经度和纬度,但是位置描述信息为null,出现的次数比较少
网络定位的情况下三者都有。

locationTime不变的情况

这里写图片描述
第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第8张图片

来自:http://bbs.lbsyun.baidu.com/forum.php?mod=viewthread&tid=87314&highlight=%E6%97%B6%E9%97%B4%E7%9B%B8%E5%90%8C

百度定位官方Demo也有说明:
这里写图片描述

鹰眼轨迹

比较简单,看着官方文档就可以完成,下面放2中图。
官方文档:鹰眼轨迹

第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第9张图片

第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第10张图片

鹰眼轨迹需要servie_id。
第三方SDK:百度地图(二)定位 + 鹰眼轨迹_第11张图片

BDLocation各属性

BDLocation location
名称 说明
getTime() 服务端出本次结果的时间,如果位置不发生变化,则时间不变
getLocType() 定位类型
getLocTypeDescription() 定位类型说明
getLatitude() 纬度
getLongitude() 经度
getRadius() 半径
getCountryCode() 国家码
getCountry() 国家名称
getCityCode() 城市编码
getCity() 城市
getDistrict()
getStreet() 街道
getAddrStr() 地址信息
getUserIndoorState() 用户室内外判断结果
getDirection() 方向
getLocationDescribe() 位置语义化信息
 if (null != location && location.getLocType() != BDLocation.TypeServerError) {
    StringBuffer sb = new StringBuffer(256);
    sb.append("time : ");
    /**
     * 时间也可以使用systemClock.elapsedRealtime()方法 获取的是自从开机以来,每次回调的时间;
     * location.getTime() 是指服务端出本次结果的时间,如果位置不发生变化,则时间不变
     */
    sb.append(location.getTime());
    sb.append("\nlocType : ");// 定位类型
    sb.append(location.getLocType());
    sb.append("\nlocType description : ");// *****对应的定位类型说明*****
    sb.append(location.getLocTypeDescription());
    sb.append("\nlatitude : ");// 纬度
    sb.append(location.getLatitude());
    sb.append("\nlontitude : ");// 经度
    sb.append(location.getLongitude());
    sb.append("\nradius : ");// 半径
    sb.append(location.getRadius());
    sb.append("\nCountryCode : ");// 国家码
    sb.append(location.getCountryCode());
    sb.append("\nCountry : ");// 国家名称
    sb.append(location.getCountry());
    sb.append("\ncitycode : ");// 城市编码
    sb.append(location.getCityCode());
    sb.append("\ncity : ");// 城市
    sb.append(location.getCity());
    sb.append("\nDistrict : ");// 区
    sb.append(location.getDistrict());
    sb.append("\nStreet : ");// 街道
    sb.append(location.getStreet());
    sb.append("\naddr : ");// 地址信息
    sb.append(location.getAddrStr());
    sb.append("\nUserIndoorState: ");// *****返回用户室内外判断结果*****
    sb.append(location.getUserIndoorState());
    sb.append("\nDirection(not all devices have value): ");
    sb.append(location.getDirection());// 方向
    sb.append("\nlocationdescribe: ");
    sb.append(location.getLocationDescribe());// 位置语义化信息
    sb.append("\nPoi: ");// POI信息
    if (location.getPoiList() != null && !location.getPoiList().isEmpty()) {
        for (int i = 0; i < location.getPoiList().size(); i++) {
            Poi poi = (Poi) location.getPoiList().get(i);
            sb.append(poi.getName() + ";");
        }
    }
    if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
        sb.append("\nspeed : ");
        sb.append(location.getSpeed());// 速度 单位:km/h
        sb.append("\nsatellite : ");
        sb.append(location.getSatelliteNumber());// 卫星数目
        sb.append("\nheight : ");
        sb.append(location.getAltitude());// 海拔高度 单位:米
        sb.append("\ngps status : ");
        sb.append(location.getGpsAccuracyStatus());// *****gps质量判断*****
        sb.append("\ndescribe : ");
        sb.append("gps定位成功");
    } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
        // 运营商信息
        if (location.hasAltitude()) {// *****如果有海拔高度*****
            sb.append("\nheight : ");
            sb.append(location.getAltitude());// 单位:米
        }
        sb.append("\noperationers : ");// 运营商信息
        sb.append(location.getOperators());
        sb.append("\ndescribe : ");
        sb.append("网络定位成功");
    } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
        sb.append("\ndescribe : ");
        sb.append("离线定位成功,离线定位结果也是有效的");
    } else if (location.getLocType() == BDLocation.TypeServerError) {
        sb.append("\ndescribe : ");
        sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到[email protected],会有人追查原因");
    } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
        sb.append("\ndescribe : ");
        sb.append("网络不同导致定位失败,请检查网络是否通畅");
    } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
        sb.append("\ndescribe : ");
        sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
    }
    logMsg(sb.toString());
    Log.d(TAG, "地址:" + location.getAddrStr());
}

官方基础定位demo

Demo: https://git.oschina.net/BaiDuMapSDK/baidulocdemo

创建类LocationService,在Application中创建LocationService对象,在需要定位的activity中注册监听和开启定位。

LocationService

LocationService不是Service,就是一个工具类。

public class LocationService {
    private LocationClient client = null;
    private LocationClientOption mOption,DIYoption;
    private Object  objLock = new Object();

    /***
     * 
     * @param locationContext
     */
    public LocationService(Context locationContext){
        synchronized (objLock) {
            if(client == null){
                client = new LocationClient(locationContext);
                client.setLocOption(getDefaultLocationClientOption());
            }
        }
    }

    /***
     * 
     * @param listener
     * @return
     */

    public boolean registerListener(BDLocationListener listener){
        boolean isSuccess = false;
        if(listener != null){
            client.registerLocationListener(listener);
            isSuccess = true;
        }
        return  isSuccess;
    }

    public void unregisterListener(BDLocationListener listener){
        if(listener != null){
            client.unRegisterLocationListener(listener);
        }
    }

    /***
     * 
     * @param option
     * @return isSuccessSetOption
     */
    public boolean setLocationOption(LocationClientOption option){
        boolean isSuccess = false;
        if(option != null){
            if(client.isStarted())
                client.stop();
            DIYoption = option;
            client.setLocOption(option);
        }
        return isSuccess;
    }

    public LocationClientOption getOption(){
        return DIYoption;
    }
    /***
     * 
     * @return DefaultLocationClientOption
     */
    public LocationClientOption getDefaultLocationClientOption(){
        if(mOption == null){
            mOption = new LocationClientOption();
            mOption.setLocationMode(LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
            mOption.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
            mOption.setScanSpan(3000);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
            mOption.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
            mOption.setIsNeedLocationDescribe(true);//可选,设置是否需要地址描述
            mOption.setNeedDeviceDirect(false);//可选,设置是否需要设备方向结果
            mOption.setLocationNotify(false);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
            mOption.setIgnoreKillProcess(true);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死   
            mOption.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
            mOption.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
            mOption.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集

            mOption.setIsNeedAltitude(false);//可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用

        }
        return mOption;
    }

    public void start(){
        synchronized (objLock) {
            if(client != null && !client.isStarted()){
                client.start();
            }
        }
    }
    public void stop(){
        synchronized (objLock) {
            if(client != null && client.isStarted()){
                client.stop();
            }
        }
    }

    public boolean requestHotSpotState(){

        return client.requestHotSpotState();

    }
}

LocationApplication

public class LocationApplication extends Application {
    public LocationService locationService;
    @Override
    public void onCreate() {
        super.onCreate();
        locationService = new LocationService(getApplicationContext());       
    }
}

在Activity中使用

public class LocationActivity extends Activity {
    private LocationService locationService;
    private Button startLocation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.location);

    }

    @Override
    protected void onStop() {
        locationService.unregisterListener(mListener); //注销掉监听
        locationService.stop(); //停止定位服务
        super.onStop();
    }

    @Override
    protected void onStart() {
        super.onStart();
        //获取locationservice实例,建议应用中只初始化1个location实例,然后使用,可以参考其他示例的activity,都是通过此种方式获取locationservice实例的
        locationService = ((LocationApplication) getApplication()).locationService;
        locationService.registerListener(mListener);
        startLocation.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                    locationService.start();
                    startLocation.setText(getString(R.string.stoplocation));       
            }
        });
    }


    /*****
     *
     * 定位结果回调,重写onReceiveLocation方法,可以直接拷贝如下代码到自己工程中修改
     *
     */
    private BDLocationListener mListener = new BDLocationListener() {

        @Override
        public void onReceiveLocation(BDLocation location) {
            // TODO Auto-generated method stub
            if (null != location && location.getLocType() != BDLocation.TypeServerError) {
               ...
            }
        }

        public void onConnectHotSpotMessage(String s, int i) {
        }
    };
}

定位的功能模块

百度定位官方Demo实现的功能:
- 判断当前是wifi还是移动热点
- 位置震动提醒

判断当前是wifi还是移动热点

类型:

LocationClient.CONNECT_HOT_SPOT_FALSE:0,不是移动热点
LocationClient.CONNECT_HOT_SPOT_TRUE:1,是移动热点
LocationClient.CONNECT_HOT_SPOT_UNKNOWN:-1,连接状态未知

先要设置请求热点类型

client.requestHotSpotState();

在回调中判断

class MyLocationListener implements BDLocationListener{

    @Override
    public void onConnectHotSpotMessage(String connectWifiMac, int hotSpotState) {
        String resT;
        if(hotSpotState == 0){
            resText = "不是移动, wifi:"+connectWifiMac;
        } else if(hotSpotState == 1){
            resText = "是wifi热点, wifi:"+connectWifiMac;
        } else if (hotSpotState == -1){
            resText = "未连接wifi";
        }
        res.setText(resText);
    }

    @Override
    public void onReceiveLocation(BDLocation arg0) {
        // TODO Auto-generated method stub
    }

}

位置提醒

先获取震动的类Vibrator`

Vibrator mVibrator =(Vibrator)getApplicationContext().getSystemService(Service.VIBRATOR_SERVICE);

注册位置提醒监听即可。

NotifyLister mNotifyLister = new NotifyLister();
mLocationClient.registerNotify(mNotifyLister);
public class NotifyLister extends BDNotifyListener{
    public void onNotify(BDLocation mlocation, float distance){
        mVibrator.vibrate(1000);//振动提醒已到设定位置附近
    }
}

同时在位置监听中还需要设置提醒点的坐标

public class NotiftLocationListener implements BDLocationListener {

    @Override
    public void onReceiveLocation(BDLocation location) {
        longtitude = location.getLongitude();
        latitude = location.getLatitude();
        notifyHandler.sendEmptyMessage(0);
    }

    public void onConnectHotSpotMessage(String s, int i){   
    }
}

(为什么要在Handler中处理?)

private Handler notifyHandler = new Handler(){

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        mNotifyLister.SetNotifyLocation(latitude,longtitude, 3000,mLocationClient.getLocOption().getCoorType());
       //4个参数代表要位置提醒的点的坐标,具体含义依次为:纬度,经度,距离范围,坐标系类型(gcj02,gps,bd09,bd09ll)
    }
};

关闭提醒

mLocationClient.removeNotifyEvent(mNotifyLister);

你可能感兴趣的:(第三方SDK)