天天看點

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

·上一篇android項目案例1- 基于Android studio的仿微信底部導航欄實作·中分享了項目中的底部導航欄子產品,有不懂的地方可以回到上一篇文章再看看,今天我要介紹一下我項目中的另一個百度地圖子產品。接下來進入主題!!!!

百度地圖有以下功能:

1. 定位

2. 選擇不同的地圖類型後顯示不同的地圖

一.在百度地圖開發者平台上申請API Key

百度地圖開發者平台位址:http://lbsyun.baidu.com/index.php?title=androidsdk。點選界面的“擷取密鑰”,進入界面之後,點選“建立應用”按鈕。将應用類型選擇為“Android SDK”,填寫你的項目應用名稱即在Android studio中建立的項目名稱、檢視釋出版本SHA1、開發版本SHA1,填寫項目包名。完成後點選送出即可成為百度開發者,獲得密鑰即應用AK。

1.擷取開發版SHA1:

輸入指令:keytool -list -v -keystore debug.keystore,回車

輸入密鑰庫密碼:android(系統預設)回車。

方法1:

打開你的安卓ADB目錄,一般在C槽的使用者目錄中以.android為檔案名。

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

這個debug檔案就是擷取SHA1值的檔案。接下來WIN+R,輸入cmd。來到指令視窗界面:先輸入cd .android來到這個檔案夾中之後輸入keytool -list -v -keystore debug.keystore

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

方法2:

在android studio的項目中查找開發版SHA1。

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

2.擷取釋出版SHA1:

要想擷取釋出版的SHA1的值,必須先對項目進行簽名,如何對項目進行簽名的,詳情請看本人覺得不錯,轉載的部落格:Android移動開發-如何在AndroidStudio裡進行對應用程式進行簽名,項目簽名後可以直接用Android Studio提供的指令控制台Terminal輸入指令時輸入“cd 自己應用簽名的jks檔案儲存的檔案目錄”然後接着回車,比如:cd D:\AndroidStudio\AndroidKey\BaiduMapTest1,接着在指令行裡輸入keytool -list -v -keystore jks檔案名,比如:keytool -list -v -keystore BaiduMapTest.jks,接着按回車,然後輸入秘鑰,回車(秘鑰庫密碼是看不到的)。如下圖所示:

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

3.申請百度地圖的API Key

得到釋出版本SHA1、開發版本SHA1後,在百度地圖開發者中心的建立應用裡分别輸入應用名稱,應用類型,開發版和釋出版的SHA1的值,包名  後點選送出,就能申請到了百度地圖的API Key了。如下圖所示

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

擷取密鑰成功(API key)

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

二.內建百度地圖

1.上百度地圖開發者網站下載下傳百度地圖SDK

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

2.将BaiduLBS_Android.jarr檔案複制到libs目錄中。

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

3.在main檔案下建立JniLibs檔案夾,将剩下的檔案拷貝到裡面。

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

4.在build.gradle檔案中設定

工程配置還需要把jar包內建到自己的工程中,如圖上圖所示,放入libs目錄下。将每個jar檔案導入到工程中。對應在build.gradle生成工程所依賴的jar檔案說明,如下所示:

ndk {
            abiFilters "armeabi","armeabi-v7a","x86"
        }

        packagingOptions {
            exclude "lib/libssl.so"
        }

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDir 'libs'
            //說明so的路徑為該libs路徑,關聯所有地圖SDK的so檔案
        }
    }
           
android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

5.在項目中的AndroidManifest.xm檔案中配置相關資料 

<!-- 百度API所需權限 -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
    <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.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
           
<!-- 百度地圖API KEY -->
        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="Ee5xOWrrxfNSkBqmLNAYdxr9ij2roADX" />
           
<!-- 百度定位服務 -->
        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote" />
           
<uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />
           

6.在布局xml檔案中添加地圖控件

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

    <com.baidu.mapapi.map.MapView
        android:id="@+id/id_bmapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="2dp"
            android:orientation="horizontal">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:gravity="center_vertical"
                    android:paddingLeft="3dp"
                    android:text="百度地圖"
                    android:textColor="#FF4500"
                    android:textSize="20sp" />
            </LinearLayout>

        </RelativeLayout>

    </LinearLayout>

</RelativeLayout>
           

7.建立Activity,實作地圖功能。

package com.CWT.navigation.fragment.TabMapFragment;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.Toast;


import com.CWT.navigation.R;
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.MapStatus;
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 TabMapFragment extends Fragment{
    private static final int BAIDU_READ_PHONE_STATE = 100;

    private MapView mMapView = null;
    private BaiduMap mBaiduMap;
    private LocationClient mlocationClient;
    private MylocationListener mlistener;
    private Context context;

    private double mLatitude;
    private double mLongitude;
    private float mCurrentX;

    private Button mGetMylocationBN;

    PopupMenu popup = null;

    private Activity mParentActivity = null;

    //自定義圖示
    private BitmapDescriptor mIconLocation;

    private MyOrientationListener myOrientationListener;
    //定位圖層顯示方式
    private MyLocationConfiguration.LocationMode locationMode;

//    public TabMapFragment(Context c){
//        this.context = c;
//    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        //引入我們的布局
        return inflater.inflate(R.layout.fragment_tab_map, container, false);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mParentActivity = this .getActivity();
        Log.d("-----------------------", mParentActivity.getApplicationContext().toString());

        SDKInitializer.initialize(mParentActivity.getApplicationContext()); //這裡可以了
        //剩下是baidu初始化找不到庫的問題,去看例子

        //mParentActivity.setContentView(R.layout.fragment_tab_map);

        this.context =mParentActivity.getApplicationContext();


    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        initView();
        //判斷是否為Android 6.0 以上的系統版本,如果是,需要動态添權重限
        if (Build.VERSION.SDK_INT >= 23) {
            showLocMap();
        } else {
            initLocation();//initLocation為定位方法
        }
        setHasOptionsMenu(true);
    }

    private void initView() {
        mMapView = (MapView) mParentActivity.findViewById(R.id.id_bmapView);

        mBaiduMap = mMapView.getMap();
        //根據給定增量縮放地圖級别
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(18.0f);
        mBaiduMap.setMapStatus(msu);
        MapStatus mMapStatus;//地圖目前狀态
        MapStatusUpdate mMapStatusUpdate;//地圖将要變化成的狀态
        mMapStatus = new MapStatus.Builder().overlook(-45).build();
        mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
        mBaiduMap.setMapStatus(mMapStatusUpdate);
    }

    /**
     * 定位方法
     */
    private void initLocation() {
        locationMode = MyLocationConfiguration.LocationMode.NORMAL;

        //定位服務的用戶端。宿主程式在用戶端聲明此類,并調用,目前隻支援在主線程中啟動
        mlocationClient = new LocationClient(context);
        mlistener = new MylocationListener();

        //注冊監聽器
        mlocationClient.registerLocationListener(mlistener);
        //配置定位SDK各配置參數,比如定位模式、定位時間間隔、坐标系類型等
        LocationClientOption mOption = new LocationClientOption();
        //設定坐标類型
        mOption.setCoorType("bd09ll");
        //設定是否需要位址資訊,預設為無位址
        mOption.setIsNeedAddress(true);
        //設定是否打開gps進行定位
        mOption.setOpenGps(true);
        //設定掃描間隔,機關是毫秒,當<1000(1s)時,定時定位無效
        int span = 1000;
        mOption.setScanSpan(span);
        //設定 LocationClientOption
        mlocationClient.setLocOption(mOption);

        //初始化圖示,BitmapDescriptorFactory是bitmap 描述資訊工廠類.
        mIconLocation = BitmapDescriptorFactory
                .fromResource(R.drawable.icon_geo);

        myOrientationListener = new MyOrientationListener(context);
        //通過接口回調來實作實時方向的改變
        myOrientationListener.setOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
            @Override
            public void onOrientationChanged(float x) {
                mCurrentX = x;
            }
        });

    }

    @Override
    public void onStart() {
        super.onStart();
        //開啟定位
        mBaiduMap.setMyLocationEnabled(true);
        if (!mlocationClient.isStarted()) {
            mlocationClient.start();
        }
        myOrientationListener.start();
    }

    @Override
    public void onStop() {
        super.onStop();
        //停止定位
        mBaiduMap.setMyLocationEnabled(false);
        mlocationClient.stop();
        myOrientationListener.stop();
    }

    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

    /**
     * 擷取我的定位
     */
    public void getMyLocation() {
        LatLng latLng = new LatLng(mLatitude, mLongitude);
        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
        mBaiduMap.setMapStatus(msu);
    }

    /**
     * 菜單欄
     * @param menu
     * @param inflater
     */
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.menu_main, menu);
    }

    /**
     * 菜單項的選擇
     * @param item
     * @return
     */
    @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_mlocation:
                                getMyLocation();
                                break;
                            case R.id.id_map_model_common:
                                //熱力圖
                                mBaiduMap.setBaiduHeatMapEnabled(true);
                                break;
                        }
                        return true;
    }


    /**
     * 所有的定位資訊都通過接口回調來實作
     */
    public class MylocationListener implements BDLocationListener {
        //定位請求回調接口
        private boolean isFirstIn = true;

        //定位請求回調函數,這裡面會得到定位資訊
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            //BDLocation 回調的百度坐标類,内部封裝了如經緯度、半徑等屬性資訊
            //MyLocationData 定位資料,定位資料建造器
            /**
             * 可以通過BDLocation配置如下參數
             * 1.accuracy 定位精度
             * 2.latitude 百度緯度坐标
             * 3.longitude 百度經度坐标
             * 4.satellitesNum GPS定位時衛星數目 getSatelliteNumber() gps定位結果時,擷取gps鎖定用的衛星數
             * 5.speed GPS定位時速度 getSpeed()擷取速度,僅gps定位結果時有速度資訊,機關公裡/小時,預設值0.0f
             * 6.direction GPS定位時方向角度
             * */
            mLatitude = bdLocation.getLatitude();
            mLongitude = bdLocation.getLongitude();
            MyLocationData data = new MyLocationData.Builder()
                    .direction(mCurrentX)//設定圖示方向
                    .accuracy(bdLocation.getRadius())//getRadius 擷取定位精度,預設值0.0f
                    .latitude(mLatitude)//百度緯度坐标
                    .longitude(mLongitude)//百度經度坐标
                    .build();
            //設定定位資料, 隻有先允許定位圖層後設定資料才會生效,參見 setMyLocationEnabled(boolean)
            mBaiduMap.setMyLocationData(data);
            //配置定位圖層顯示方式,三個參數的構造器
            /**
             * 1.定位圖層顯示模式
             * 2.是否允許顯示方向資訊
             * 3.使用者自定義定位圖示
             * */
            MyLocationConfiguration configuration
                    = new MyLocationConfiguration(locationMode, true, mIconLocation);
            //設定定位圖層配置資訊,隻有先允許定位圖層後設定定位圖層配置資訊才會生效,參見 setMyLocationEnabled(boolean)
            mBaiduMap.setMyLocationConfigeration(configuration);
            //判斷是否為第一次定位,是的話需要定位到使用者目前位置
            if (isFirstIn) {
                //地理坐标基本資料結構
                LatLng latLng = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
                //描述地圖狀态将要發生的變化,通過目前經緯度來使地圖顯示到該位置
                MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
                //改變地圖狀态
                mBaiduMap.setMapStatus(msu);
                isFirstIn = false;
                Toast.makeText(context, "您目前的位置為:" + bdLocation.getAddrStr(),Toast.LENGTH_LONG).show();
            }
        }
    }

    /**
     * Android 6.0 以上的版本的定位方法
     */
    public void showLocMap() {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(getContext(), "沒有權限,請手動開啟定位權限", Toast.LENGTH_SHORT).show();
            // 申請一個(或多個)權限,并提供用于回調傳回的擷取碼(使用者定義)
            ActivityCompat.requestPermissions(mParentActivity,new String[]{
                    Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_PHONE_STATE
            }, BAIDU_READ_PHONE_STATE);
      }
           else {
            initLocation();
        }
    }

    //Android 6.0 以上的版本申請權限的回調方法
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            // requestCode即所聲明的權限擷取碼,在checkSelfPermission時傳入
            case BAIDU_READ_PHONE_STATE:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 擷取到權限,作相應處理(調用定位SDK應當確定相關權限均被授權,否則可能引起定位失敗)
                    initLocation();
                } else {
                    // 沒有擷取到權限,做特殊處理
                    Toast.makeText(getContext(), "擷取位置權限失敗,請手動開啟", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                break;
        }
    }

}




           

完成以上全部步驟,即可運作項目,

效果圖如下:

android項目案例2- 基于Android studio的android百度地圖一.在百度地圖開發者平台上申請API Key 二.內建百度地圖

請各位大神指教,本博文内容可能寫的有錯誤,但程式沒錯誤,程式是我調了很久,請教了老師後才完成的,期間跳了很多坑,也填了很多坑,希望本博文能夠幫到大家。