您的位置:首页 > 其它

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

2016-08-19 13:35 309 查看
#1 基础地图 + 基础定位#

可以看到地图的界面。

如图:



Menu:

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