1. 程式人生 > >Android百度地圖api呼叫

Android百度地圖api呼叫

1.首先,準備工作。前往百度地圖開放平臺

  • 註冊百度開發者賬號,建立應用,獲取API key
    地址:http://lbsyun.baidu.com/apiconsole/key
  • 建立應用需要應用的數字簽名SHA1和包名
    SHA1可以通過雙擊gradle裡面的signingReport

在這裡插入圖片描述
便會在在下方出現圖示SHA1值
在這裡插入圖片描述
包名,直接開啟AndroidManifest.xml檔案複製package後面的值過去即可
在這裡插入圖片描述

2. 標題下載完之後,把SDK解壓,出現libs和readme

在這裡插入圖片描述
然後把libs的檔案全部拷貝到Android工程的libs資料夾(沒有就新建一個)
在這裡插入圖片描述

3.在app目錄下的build.gradle檔案裡面新增一下程式碼

 defaultConfig {
 sourceSets{
        main{
            //說明so的路徑為該libs路徑,關聯所有地圖SDK的so檔案,用於生成jniLibs資料夾
            jniLibs.srcDirs = ['libs']

        }
    }
dependencies {
compile fileTree(dir:  'libs' , include: ['*.jar'])
    compile files('libs/BaiduLBS_Android.jar')
    }

當新增完jniLibs.srcDirs = [‘libs’]之後會自動生成jniLibs資料夾不過需要從project切換到android才能看到(注意:網上很多教程裡面寫到需要在res裡面新建一個jniLibs資料夾把libs的複製過去,試過但是好像不起作用,所以建議新增上述程式碼自動生成)
在這裡插入圖片描述

4.在AndroidManifest.xml檔案新增許可權、註冊後臺service以及新增百度SDK(android:value裡面的值要改為之前申請到的AK)

//百度地圖許可權申請
    <!-- 這個許可權用於進行網路定位-->
    <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" />

<application
      <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="你之前申請到的AK"/>
      <activity android:name=".ForegroundActivity"/>
      //用於展示的Activity
     <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote"/>
           
  </application>

5.新建一個Activity(此處採用百度地圖提供的demo原始碼)

package com.example.a26792.myapplication;

import android.app.Activity;

/**
 * Created by ${Saujyun} on 2018/12/23.
 */

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
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.DotOptions;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.example.a26792.myapplication.Toolkit.NotificationUtils;


/**
 * 適配Android 8.0限制後臺定位的功能,新增允許後臺定位的介面,即開啟一個前臺定位服務
 */
public class ForegroundActivity extends Activity {
    private LocationClient mClient;
    private MyLocationListener myLocationListener = new MyLocationListener();

    private MapView mMapView;
    private BaiduMap mBaiduMap;
    private Button mForegroundBtn;

    private NotificationUtils mNotificationUtils;
    private Notification notification;

    private boolean isFirstLoc = true;
    private boolean isEnableLocInForeground = false;


    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        //SDK初始化,demo程式碼裡面沒有,測試之後新增
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.foreground);

        initViews();
        // 定位初始化
        mClient = new LocationClient(this);
        LocationClientOption mOption = new LocationClientOption();
        mOption.setScanSpan(5000);
        mOption.setCoorType("bd09ll");
        mOption.setIsNeedAddress(true);
        mOption.setOpenGps(true);
        mClient.setLocOption(mOption);
        mClient.registerLocationListener(myLocationListener);
        mClient.start();

        //設定後臺定位
        //android8.0及以上使用NotificationUtils
        if (Build.VERSION.SDK_INT >= 26) {
            mNotificationUtils = new NotificationUtils(this);
            Notification.Builder builder2 = mNotificationUtils.getAndroidChannelNotification
                    ("適配android 8限制後臺定位功能", "正在後臺定位");
            notification = builder2.build();
        } else {
            //獲取一個Notification構造器
            Notification.Builder builder = new Notification.Builder(ForegroundActivity.this);
            Intent nfIntent = new Intent(ForegroundActivity.this, ForegroundActivity.class);

            builder.setContentIntent(PendingIntent.
                    getActivity(ForegroundActivity.this, 0, nfIntent, 0)) // 設定PendingIntent
                    .setContentTitle("適配android 8限制後臺定位功能") // 設定下拉列表裡的標題
                    .setSmallIcon(R.drawable.blue) // 設定狀態列內的小圖示
                    .setContentText("正在後臺定位") // 設定上下文內容
                    .setWhen(System.currentTimeMillis()); // 設定該通知發生的時間

            notification = builder.build(); // 獲取構建好的Notification
        }
        notification.defaults = Notification.DEFAULT_SOUND; //設定為預設的聲音
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
        mMapView = null;
        mClient.disableLocInForeground(true);
        mClient.unRegisterLocationListener(myLocationListener);
        mClient.stop();
    }


    private void initViews(){
        mForegroundBtn = (Button) findViewById(R.id.bt_foreground);
        mForegroundBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(isEnableLocInForeground){
                    //關閉後臺定位(true:通知欄消失;false:通知欄可手動劃除)
                    mClient.disableLocInForeground(true);
                    isEnableLocInForeground = false;
                    mForegroundBtn.setText(R.string.startforeground);
                } else {
                    //開啟後臺定位
                    mClient.enableLocInForeground(1, notification);
                    isEnableLocInForeground = true;
                    mForegroundBtn.setText(R.string.stopforeground);
                }
            }
        });
        mMapView = (MapView) findViewById(R.id.mv_foreground);
        mBaiduMap = mMapView.getMap();
        mBaiduMap.setMyLocationEnabled(true);
    }


    class  MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            if (bdLocation == null || mMapView == null) {
                return;
            }
            MyLocationData locData = new MyLocationData.Builder().accuracy(bdLocation.getRadius())
                    // 此處設定開發者獲取到的方向資訊,順時針0-360
                    .direction(bdLocation.getDirection()).latitude(bdLocation.getLatitude())
                    .longitude(bdLocation.getLongitude()).build();
            // 設定定位資料
            mBaiduMap.setMyLocationData(locData);
            //地圖SDK處理
            if (isFirstLoc) {
                isFirstLoc = false;
                LatLng ll = new LatLng(bdLocation.getLatitude(),
                        bdLocation.getLongitude());
                MapStatus.Builder builder = new MapStatus.Builder();
                builder.target(ll).zoom(18.0f);
                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
            }
            LatLng point = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
            OverlayOptions dotOption = new DotOptions().center(point).color(0xAAFF0000);
            mBaiduMap.addOverlay(dotOption);
        }
    }

}

6.新建一個layout檔案

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/bt_foreground"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="@string/startforeground" />

    <com.baidu.mapapi.map.MapView
        android:id="@+id/mv_foreground"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </com.baidu.mapapi.map.MapView>

</LinearLayout>

7.途中出現的問題集錦

1.丟擲異常“ java.lang.UnsatisfiedLinkError: dlopen failed: /data/app/com.smallvideo-1/lib/arm/libutility.so: has”
解決辦法:在自己工程app目錄下build.gradle加上一句話:

defaultConfig {
 ndk{
            abiFilters "armeabi"
            //這句話意思是隻載入32位的so檔案,那麼如果是64位系統的手機肯定也是可以相容的。
        }
  }

原連結:https://blog.csdn.net/caonidayeheixiu8/article/details/78831244

  1. 丟擲異常“error inflating class com.baidu.mapapi.map.mapview"
    解決辦法:其實都是一個原因 就是 初始化
    在 onCreate()中加入SDKInitializer.initialize(getApplicationContext());即可
    //示例程式碼已經新增
    原連結:https://www.cnblogs.com/dubo-/p/8059460.html