在相關下載裏下載最新的庫文件。將so文件的壓縮文件解壓出來,把對應架構下的so文件放入開發者自己APP的對應架構下的文件夾中(建議全部放入以提高程序兼容性),將locSDK_6.X.jar文件拷貝到工程的libs目錄下,這樣您就可以在程序中使用百度定位SDK了。
使用eclipse開發的開發者,只需要將SO的文件夾放到libs下即可;使用AndroidStutio的開發者除了上述操作,還需要在build.gradle中配置SO的使用,如下所示:
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
開發者如果開發的是系統應用,則只在工程中配置SO還是不夠的,還需要手動把對應架構的SO拷貝到/system/lib下,如果是64位系統的話需要將64位的SO拷貝到/sytem/lib64下。
注意:每次新版本的定位SDK,開發者除了要更新JAR包之外,也要注意一下SO有無更新,如果SO名稱不一樣了,也要及時替換老的SO版本,不然會導致定位失敗!
設置AndroidManifest.xml
在application標籤中聲明service組件,每個app擁有自己單獨的定位service
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote">
</service>
【重要提醒】
定位SDKv3.1版本之後,以下權限已不需要,請取消聲明,否則將由於Android 5.0多帳戶系統加強權限管理而導致應用安裝失敗。 <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE"></uses-permission>
聲明使用權限
<!-- 這個權限用於進行網絡定位-->
<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>
設置AcessKey
SDK4.2及之後版本需要在Mainfest.xml設置Accesskey,設置有誤會引起定位和地理圍欄服務不能正常使用,必須進行Accesskey的正確設置。
設置AccessKey,在application標籤中加入
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="key" /> //key:開發者申請的key
import相關類
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.BDNotifyListener;//假如用到位置提醒功能,需要import該類
import com.baidu.location.Poi;
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.util.Log;
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 {
/**
* @Field @mMapView : TODO(XML中用於顯示地圖的控件)
*/
private MapView mMapView;
/**
* @Field @mBaiduMap : TODO(定義 BaiduMap 地圖對象的操作方法與接口)
*/
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;// bitmap 描述信息
private MyOrientationListener myOrientationListener;
private float mCurrentX;
private LocationMode mLocationMode;
// 覆蓋物相關
private BitmapDescriptor mMarker;
private RelativeLayout mMarkerLy;
/*
* (非 Javadoc) Description:
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@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);
try {
getWindow().addFlags(WindowManager.LayoutParams.class.getField("FLAG_NEEDS_MENU_KEY").getInt(null));
} catch (NoSuchFieldException e) {
// Ignore since this field won't exist in most versions of Android
} catch (IllegalAccessException e) {
Log.w("feelyou.info", "Could not access FLAG_NEEDS_MENU_KEY in addLegacyOverflowButton()", e);
}
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
this.context = this;
initView();
// 初始化定位
initLocation();
initMarker();
mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() {
// 設置地圖 Marker 覆蓋物點擊事件監聽者,自3.4.0版本起可設置多個監聽對象,停止監聽時調用removeMarkerClickListener移除監聽對象
@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();// 隱藏當前 InfoWindow
}
});
mBaiduMap.showInfoWindow(infoWindow);// 顯示 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();// 隱藏當前 InfoWindow
}
});
}
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);// 設置地圖類型 MAP_TYPE_NORMAL 普通圖; MAP_TYPE_SATELLITE
// 衛星圖;MAP_TYPE_NONE 衛星圖
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();// 清空地圖所有的 Overlay 覆蓋物以及 InfoWindow
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);// 向地圖添加一個 Overlay
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);// 以動畫方式更新地圖狀態,動畫耗時 300 ms
}
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);// 設置定位數據, 只有先允許定位圖層後設置數據纔會生效,參見 setMyLocationEnabled(boolean)
// 設置自定義圖標
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);// 以動畫方式更新地圖狀態,動畫耗時 300 ms
isFirstIn = false;
Toast.makeText(context, location.getAddrStr(), Toast.LENGTH_SHORT).show();
}
}
}
}