第三方SDK:百度地图(二)定位 + 鹰眼轨迹
2016-08-19 13:35
309 查看
#1 基础地图 + 基础定位#
可以看到地图的界面。
注意:只是实现基础定位功能,是不需要在application中声明context的!!!!
声明定位service:
有的版本指定service,所以要看清下载的sdk+demo,最好复制demo的
定位key:
没有调用initLocation()方法时,打印的log为:
调用initLocation()方法时,打印的log为:
注意:按照百度基本定位SDK文档说明,定位用的一个API_key是不可以对应多个包名的,但我在实际测试中发现定位的一个key,可以对应多个包名(各位可以尝试修改本demo的applicationId,会发现log仍然有地址)。但是仅限定位,基本地图就不可以。
源码:
源码下载:https://github.com/s1168805219/jichudingwei
源码:https://git.oschina.net/BaiDuMapSDK/DingWei03
经纬度是0:表示没有获取到经纬度坐标,默认值都是:Double.MIN_VALUE,也就是0
可能是没开GPS,也可能是没给位置权限
GPS定位的情况下会出现这种情况:有经度和纬度,但是位置描述信息为null,出现的次数比较少
网络定位的情况下三者都有。
来自: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也有说明:
官方文档:鹰眼轨迹
鹰眼轨迹需要servie_id。
创建类
- 判断当前是wifi还是移动热点
- 位置震动提醒
先要设置请求热点类型
在回调中判断
注册位置提醒监听即可。
同时在位置监听中还需要设置提醒点的坐标
(为什么要在Handler中处理?)
关闭提醒
可以看到地图的界面。
如图:
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/key2 环境配置
步骤:
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);
相关文章推荐
- 百度地图- - - 鹰眼轨迹- - - -实时定位
- 【第三方SDK】百度地图实现最简单的定位功能(无地图界面)
- 【第三方SDK】百度地图实现最简单的定位功能(无地图界面)
- Android百度地图(一):百度地图定位sdk 类方法参数、定位原理详细介绍
- Android定位SDK_百度地图开发
- android使用百度地图、定位SDK实现地图和定位功能!(最新、可用+吐槽)
- Android 百度地图最新SDK v3.2.0和Android定位SDK:v5.0应用(3)
- iOS开发-开发百度地图2-iOS SDK 3.0.0-定位及geo检索服务
- 第四十五天 百度地图定位SDK
- Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!
- 百度地图定位SDKv4.2版本(android)的使用教程
- android使用百度地图、定位SDK实现地图和定位功能!(最新、可用+吐槽)
- Android第三方集成之百度地图定位
- 第三方SDK:百度地图(一)HelloBaiduMap
- Android中第三方SDK集成之百度地图集成(案例一)
- Android百度地图(一):百度地图定位sdk 类方法参数、定位原理详细介绍
- 无需第三方sdk支持的定位功能实现
- 百度地图后台持续定位<定位SDK-6.13>
- Android 第三方SDK 之百度定位(省-市-区)
- Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!