百度地圖sdk的簡單應用
最近研究了很多的第三方sdk,今天稍微簡單的研究下百度sdk,打個基礎,做個記錄,方便以後深入研究,
本文主要實現百度地圖基本的型別和定位自己的位置功能
最終效果圖如下:
進入介面後,會自動定位到自己的位置,然後有幾個基本的型別,都是很基本的功能,如果以後有這方面的需求,在繼續深入研究
進入百度開發中心
沒有賬號的註冊一個賬號吧
小夥伴可以自行勾選
然後點選下載開發包
把lib檔案拷貝到自己的工程裡面去
然後在src/main/目錄下新建jniLibs目錄
放入.so檔案
上面這些配置,官網都有記載的,主要是功能的實現和一些bug的出現是個比較煩人的問題
記得在build.gradle(app)裡面加上
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
好,接下來去申請key
點選建立應用
這裡主要講解一下發布版的sha1怎麼獲取
獲得這個應該不難,就不細說了
我們都有預設的debug.keystore的,用這個測試好了,當然你有自己的簽名檔案的話,直接用自己的簽名檔案
找到自己的.android檔案,然後找到debug.keystore
進入debug.keystore所在的目錄
直接敲keytool -list -v -keystore debug.keystore
然後輸入密令android
就能得到了
然後輸入包名,包名在我們的每個java檔案上面都有的
這樣提交後,我們就有獲得appkey了,
填寫到manifest中,如下
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.anlaiye.swt.baidumapdemo"> <application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="這裡輸入你的appkey就行了" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <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> </application> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> </manifest>
我們在使用百度地圖相關功能的時候,都需要先例項化,但是每一次都例項化就比較麻煩,所以從上面的配置檔案中可以看到我建立了一個application,
程式碼很簡單,就是例項化了百度地圖SDK
package com.anlaiye.swt.baidumapdemo;
import android.app.Application;
import com.baidu.mapapi.SDKInitializer;
/**
* Created by pc on 2016/12/14.
*/
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
SDKInitializer.initialize(this);
}
}
接下來上佈局檔案
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clickable="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/select_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="選擇型別" />
<Button
android:id="@+id/dingwei"
android:onClick="location"
android:text="定位自己"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
mapview就是百度地圖的介面,你需要設定多大就設定多大
我下面加了按鈕,實現一些功能
這是type.xml的程式碼
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent">
<LinearLayout
android:layout_marginBottom="35dp"
android:background="@android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="weixin"
android:text="衛星圖" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/white"
android:onClick="nomal"
android:text="正常圖" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="none"
android:text="空白圖" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/white"
android:onClick="jiaotong"
android:text="交通圖" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="hotjiaotong"
android:text="熱力交通圖" />
</LinearLayout>
</RelativeLayout>
每個按鈕都加了onclick事件,直接寫在了mainactivity中
package com.anlaiye.swt.baidumapdemo;
import android.app.Dialog;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.PopupWindow;
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.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private MapView mMapView = null;
private BaiduMap mBaiduMap;
private Button type_button;
private Dialog dialog;
private PopupWindow mPopupWindow;
private LocationManager mgr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在使用SDK各元件之前初始化context資訊,傳入ApplicationContext
//注意該方法要再setContentView方法之前實現
SDKInitializer.initialize(this);
setContentView(R.layout.activity_main);
//獲取地圖控制元件引用
mMapView = (MapView) findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
type_button = (Button) findViewById(R.id.select_type);
type_button.setOnClickListener(this);
initOritationListener();
initMyLocation();
}
public void weixin(View view) {
//衛星地圖
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
// dialog.cancel();
}
public void nomal(View view) {
//正常地圖
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
// dialog.cancel();
}
public void none(View view) {
//空白圖
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
// dialog.cancel();
}
public void jiaotong(View view) {
//交通圖
mBaiduMap.setTrafficEnabled(true);
// dialog.cancel();
}
public void hotjiaotong(View view) {
//熱力交通圖
mBaiduMap.setBaiduHeatMapEnabled(true);
// dialog.cancel();
}
/**
* 定位的客戶端
*/
private LocationClient mLocationClient;
/**
* 定位的監聽器
*/
public MyLocationListener mMyLocationListener;
/**
* 當前定位的模式
*/
private MyLocationConfiguration.LocationMode mCurrentMode = MyLocationConfiguration.LocationMode.NORMAL;
/***
* 是否是第一次定位
*/
private volatile boolean isFristLocation = true;
/**
* 最新一次的經緯度
*/
private double mCurrentLantitude;
private double mCurrentLongitude;
/**
* 當前的精度
*/
private float mCurrentAccracy;
/**
* 方向感測器的監聽器
*/
private MyOrientationListener myOrientationListener;
/**
* 方向感測器X方向的值
*/
private int mXDirection;
private void initOritationListener()
{
myOrientationListener = new MyOrientationListener(
getApplicationContext());
myOrientationListener
.setOnOrientationListener(new MyOrientationListener.OnOrientationListener()
{
@Override
public void onOrientationChanged(float x)
{
mXDirection = (int) x;
// 構造定位資料
MyLocationData locData = new MyLocationData.Builder()
.accuracy(mCurrentAccracy)
// 此處設定開發者獲取到的方向資訊,順時針0-360
.direction(mXDirection)
.latitude(mCurrentLantitude)
.longitude(mCurrentLongitude).build();
// 設定定位資料
mBaiduMap.setMyLocationData(locData);
// 設定自定義圖示
BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory
.fromResource(R.mipmap.navi_map_gps_locked);
MyLocationConfiguration config = new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker);
mBaiduMap.setMyLocationConfigeration(config);
}
});
}
/**
* 初始化定位相關程式碼
*/
private void initMyLocation() {
// 定位初始化
mLocationClient = new LocationClient(this);
mMyLocationListener = new MyLocationListener();
mLocationClient.registerLocationListener(mMyLocationListener);
// 設定定位的相關配置
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);// 開啟gps
option.setCoorType("bd09ll"); // 設定座標型別
option.setScanSpan(1000);
mLocationClient.setLocOption(option);
}
public void location(View view) {
LatLng ll = new LatLng(mCurrentLantitude, mCurrentLongitude);
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.animateMapStatus(u);
}
@Override
protected void onStart() {
// 開啟圖層定位
mBaiduMap.setMyLocationEnabled(true);
if (!mLocationClient.isStarted()) {
mLocationClient.start();
}
// 開啟方向感測器
myOrientationListener.start();
super.onStart();
}
@Override
protected void onStop() {
// 關閉圖層定位
mBaiduMap.setMyLocationEnabled(false);
mLocationClient.stop();
// 關閉方向感測器
myOrientationListener.stop();
super.onStop();
}
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// map view 銷燬後不在處理新接收的位置
if (location == null || mMapView == null)
return;
// 構造定位資料
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此處設定開發者獲取到的方向資訊,順時針0-360
.direction(mXDirection).latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
mCurrentAccracy = location.getRadius();
// 設定定位資料
mBaiduMap.setMyLocationData(locData);
mCurrentLantitude = location.getLatitude();
mCurrentLongitude = location.getLongitude();
// 設定自定義圖示
BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory
.fromResource(R.mipmap.navi_map_gps_locked);
MyLocationConfiguration config = new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker);
mBaiduMap.setMyLocationConfigeration(config);
// 第一次定位時,將地圖位置移動到當前位置
if (isFristLocation) {
isFristLocation = false;
LatLng ll = new LatLng(location.getLatitude(),
location.getLongitude());
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.animateMapStatus(u);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity執行onDestroy時執行mMapView.onDestroy(),實現地圖生命週期管理
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity執行onResume時執行mMapView. onResume (),實現地圖生命週期管理
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity執行onPause時執行mMapView. onPause (),實現地圖生命週期管理
mMapView.onPause();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.select_type:
//這是對話方塊展示,都可以實現,稍微調整一下位置
/* View typeview = LayoutInflater.from(this).inflate(R.layout.type, null);
dialog = new Dialog(this, R.style.CustomDialog);
dialog.setContentView(typeview);
Window dialogWindow = dialog.getWindow();
// WindowManager.LayoutParams lp = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.BOTTOM | Gravity.LEFT);
dialog.show();*/
//這是popwindows方式展示
View typeview = LayoutInflater.from(this).inflate(R.layout.type, null);
mPopupWindow = new PopupWindow(typeview, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, true);
mPopupWindow.setTouchable(true);
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.getContentView().setFocusableInTouchMode(true);
mPopupWindow.getContentView().setFocusable(true);
mPopupWindow.setBackgroundDrawable(new BitmapDrawable(getResources(), (Bitmap) null));//這句加上之後,點選背景才能去掉popwindows
mPopupWindow.showAtLocation(type_button, Gravity.BOTTOM | Gravity.LEFT, 0, 0);
break;
}
}
}
都註釋的很詳細,這裡參考了鴻洋大神的百度sdk開發,不過鴻洋大神那個時候的sdk比較老了,所以我在看了後,用現在最新的重新實現了一下這些簡單的功能,做個記錄,
下面是MyOrientationListener的程式碼,用來監聽定位後相關的操作
package com.anlaiye.swt.baidumapdemo;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
public class MyOrientationListener implements SensorEventListener
{
private Context context;
private SensorManager sensorManager;
private Sensor sensor;
private float lastX ;
private OnOrientationListener onOrientationListener ;
public MyOrientationListener(Context context)
{
this.context = context;
}
// 開始
public void start()
{
// 獲得感測器管理器
sensorManager = (SensorManager) context
.getSystemService(Context.SENSOR_SERVICE);
if (sensorManager != null)
{
// 獲得方向感測器
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
}
// 註冊
if (sensor != null)
{//SensorManager.SENSOR_DELAY_UI
sensorManager.registerListener(this, sensor,
SensorManager.SENSOR_DELAY_UI);
}
}
// 停止檢測
public void stop()
{
sensorManager.unregisterListener(this);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
}
@Override
public void onSensorChanged(SensorEvent event)
{
// 接受方向感應器的型別
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION)
{
// 這裡我們可以得到資料,然後根據需要來處理
float x = event.values[SensorManager.DATA_X];
if( Math.abs(x- lastX) > 1.0 )
{
onOrientationListener.onOrientationChanged(x);
}
// Log.e("DATA_X", x+"");
lastX = x ;
}
}
public void setOnOrientationListener(OnOrientationListener onOrientationListener)
{
this.onOrientationListener = onOrientationListener ;
}
public interface OnOrientationListener
{
void onOrientationChanged(float x);
}
}
好了,簡單的功能實現都在這裡了
有很多人的地圖只有網格沒有,地圖出來,這種情況一般是appkey的問題,也就是你的sha1值可能不對,(包名寫錯的人還是很少的)
230 uid: -1 appid -1 msg: APP Scode碼校驗失敗
比如這個錯誤
http://download.csdn.net/detail/qq_15527709/9715042
可以在這裡下載apk安裝到手機上面,輸入包名,獲取sha1值