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

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

如图:

这里写图片描述

<menu xmlns:android="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="罗盘模式"/>

</menu>

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<Info> 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)

先下载基础定位:

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

这里写图片描述

配置jar+so文件

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

这里写图片描述

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

网络权限:

<!-- 这个权限用于进行网络定位-->
    <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>

声明定位service:

<!--声明定位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:

 <!--百度地图:定位功能key: tpiB1a5OmkkFz4ZYSRyByp9bqHYjML4D-->
 <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号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
            } 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<Poi> 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为:
这里写图片描述
调用initLocation()方法时,打印的log为:
这里写图片描述

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

源码:

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

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

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

这里写图片描述

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号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
            } 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<Poi> 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

这里写图片描述

相关博文

重拾百度定位之踩坑篇

定位问题

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

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

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

locationTime不变的情况

这里写图片描述
这里写图片描述

来自: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中图。
官方文档:鹰眼轨迹

这里写图片描述

这里写图片描述

鹰眼轨迹需要servie_id。
这里写图片描述

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号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
    } 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);
  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值