天天看點

#夏日挑戰賽#出行品類HarmonyOS高德地圖內建過程分享項目背景邏輯實作

本文正在參加星光計劃3.0--夏日挑戰賽

項目背景

電動車因騎行友善、節省時間等優勢,成為我們日常出行的交通工具之一,國内電動車的需求資料龐大且逐年攀升。然而電動車頻繁被盜也不是新聞了,不僅給使用者帶來煩惱,也給警務工作增加負擔。如何制定一套提升使用者體驗又能兼顧高安全性的出行品類解決方案,是我們主要思考研究的方向。

為了提升及改善日常出行品類的使用者體驗,讓手機成為電動車鑰匙無感解鎖,我們想到可利用藍牙靠近發現的特性,采用無鑰匙解鎖控車作為主要功能,實作裝置快速連接配接。但是常見的電動車、童車等出行類産品均在戶外使用,其安全性要求極高,雖然可利用藍牙技術進行極簡連接配接控制,但由于藍牙本身具有開放廣播的特性,在裝置附近的人都可以通過手機發現裝置,則會帶來嚴重的安全隐患。

針對此問題,經過反複推敲,最終決定利用安全秘鑰結合雲服務,在裝置發現、連接配接操控進行嚴格的操作認證管控,實作極簡連接配接體驗和嚴格安全控車需求;結合GPS、電子地圖,實作裝置的出行軌迹展示功能,動态計算裝置的停留點、停留時間;采用出行産品電子圍欄技術,使用者通過手機直接在電子地圖上圈定範圍區域,如果裝置被移到範圍外,手機就會收到報警通知,防止車輛丢失。

邏輯實作

手機靠近電動車裝置,手機藍牙打開在未連接配接的情況下,手機将彈出連接配接提示,連接配接後将跳轉至App,可綁定裝置以及檢視相關狀态,綁定後通過手機一鍵控制開關。設定自動鎖車的時間,超過設定的時間限制,裝置将會自動下電并設防。設定電子圍欄,下電設防之後,防盜報警裝置啟動,超出區域報警提示。

以下為App部分效果圖:

#夏日挑戰賽#出行品類HarmonyOS高德地圖內建過程分享項目背景邏輯實作
#夏日挑戰賽#出行品類HarmonyOS高德地圖內建過程分享項目背景邏輯實作
#夏日挑戰賽#出行品類HarmonyOS高德地圖內建過程分享項目背景邏輯實作

電子地圖采用高德地圖,接下來我們看HarmonyOS高德地圖內建程式具體實作過程:

1.為項目增加高德地圖依賴包

依賴包放入子產品src同級目錄libs

基礎依賴:mapslibrary-release.har

搜尋功能:searchlibrary-release.har

子產品build.gradle檔案中配置

    implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
    ...
}

           

聲明權限:子產品config.json檔案中配置網絡權限

"reqPermissions": [
  {
    "name": "ohos.permission.INTERNET"
  }
]
...

           

在項目初始化-MyApplication.onInitialize() 方法中加入如下代碼啟用

// 搜尋
ServiceSettings.getInstance().setApiKey(key);

// 地圖
MapsInitializer.setApiKey(key);

           

key需在高德開放平台-控制台-應用管理-我的應用 中為應用添加key,詳見:https://lbs.amap.com/api/harmonyos-sdk/guide/get-key

2.建立地圖

xml中使用标簽

使用時建議将高度和寬度設為match_parent,如需更靈活使用則需要在代碼中建立。

    ohos:id="$+id:mapview"
    ohos:height="match_parent"
    ohos:width="match_parent"
    />
MapView mapView = (MapView) findComponentById(ResourceTable.Id_mapview);
mapView.onCreate(null);
mapView.onResume();
AMap aMap = mapView.getMap();//地圖操作對象

           

代碼中建立

final CameraPosition LUJIAZUI = new CameraPosition.Builder()
        .target(new LatLng(31.238068, 121.501654)).zoom(18).build();

AMapOptions aOptions = new AMapOptions();
aOptions.rotateGesturesEnabled(false);//設定地圖是否可以通過手勢進行旋轉。
aOptions.zoomGesturesEnabled(true);//設定地圖是否可以通過手勢進行縮放。
aOptions.scrollGesturesEnabled(true);//設定地圖是否可以通過手勢滑動
aOptions.tiltGesturesEnabled(false);//設定地圖是否可以通過手勢傾斜(3D效果),預設為true。
aOptions.compassEnabled(false);//設定指南針是否可用。
aOptions.scaleControlsEnabled(false);//設定地圖是否顯示比例尺,預設為false。
aOptions.zoomControlsEnabled(true);//設定地圖是否允許縮放。
aOptions.camera(LUJIAZUI);//設定地圖初始化時的地圖視窗狀态
aOptions.logoPosition(AMapOptions.LOGO_POSITION_BOTTOM_LEFT);//logo位置
aOptions.mapType(AMap.MAP_TYPE_NORMAL);//MAP_TYPE_NIGHT 黑夜地圖,夜間模式,值為3

MapView mapView = new MapView(this, aOptions);
ComponentContainer.LayoutConfig layoutConfig = new ComponentContainer.LayoutConfig(
        ComponentContainer.LayoutConfig.MATCH_PARENT,
        AttrHelper.vp2px(700, this));
layoutConfig.setMarginTop(AttrHelper.vp2px(56, this));

directionalLayout.addComponent(mapView, layoutConfig);
mapView.onCreate(null);
mapView.onResume();
AMap aMap = mapView.getMap();
//縮放按鈕右側居中
aMap.getUiSettings().setZoomPosition(AMapOptions.ZOOM_POSITION_RIGHT_CENTER);

           

建立後不用時記得銷毀

建議包含mapView的頁面單獨用一個PageAbility承載

@Override
protected void onStop() {
    super.onStop();
    if (mapView != null) {
        mapView.onDestroy();
    }
}

           

3.常用配置

CameraPosition

aMap.moveCamera(CameraUpdateFactory.newCameraPosition(
  new CameraPosition.Builder()
  .target(new LatLng(31.238068,121.501654)).zoom(18).build()));//地圖移動視窗

           

常用使用屬性:

(LatLng) target:目前區域螢幕中心經緯度坐标.

(float) zoom:目标可視區域的縮放級别(放大級别),3.0f時地圖可視區域最大、20.0f時地圖可視區域最小

常用 Listener

調用 aMap.setXXXListener() 設定

OnMapLoadedListener 地圖加載完成監聽接口

AMapGestureListener 地圖手勢識别的回調接口(如禁用手勢,識别到相關手勢也會回調,但OnCameraChangeListener不會觸發)

OnCameraChangeListener 地圖Camera狀态發生變化的監聽接口.當調用AMap.animateCamera(CameraUpdate)、AMap.moveCamera(CameraUpdate)及手勢操作地圖時會觸發該回調(即目前可視視窗變化監聽)。

UiSettings

UiSettings uiSettings = aMap.getUiSettings();

可設定地圖logo、比例尺、縮放按鈕、定位按鈕、指南針顯示,還可設定旋轉手勢、拖拽手勢、傾斜手勢、縮放手勢、雙指縮放手勢是否可用(屏蔽地圖底層操作)

Projection

用于螢幕像素點坐标系統和地球表面經緯度點坐标系統之間的變換。

public LatLng fromScreenLocation(Point var1) //将螢幕坐标轉換成地理坐标。

public Point toScreenLocation(LatLng var1) //将地理坐标轉換成螢幕坐标

public VisibleRegion getVisibleRegion() //傳回目前可視區域(包含MapView四個角點的經緯度坐标)坐标資訊。

           

4.常見問題解答

在開發過程中,我們經常會遇到以下問題:

1.在xml使用标簽再從代碼中擷取MapView對象,地圖已預設初始化,預設地圖中心為北京市,縮放級别為10.0f,需要調用aMap.moveCamera()方法将視窗移至我們想要的位置,aMap.moveCamera()方法會觸發OnCameraChangeListener監聽。

2.Projection.toScreenLocation()方法是基于目前視窗中心點及縮放級别計算的螢幕坐标,該坐标可能會超出螢幕顯示區域,尤其是地圖初始化還未移動視窗時調用。

3.不太建議在監聽回調接口中觸發其他監聽,可能造成邏輯或優先級沖突(如在AMapGestureListener監聽回調中調用aMap.moveCamera()方法進而又觸發了OnCameraChangeListener監聽)。

4.使用地圖後退出頁面,地圖出現在其他頁面底層,原因為地圖使用後未銷毀,建議包含mapView的頁面單獨用一個PageAbility承載,在Ability.onStop()方法中調用mapView的onDestroy()方法銷毀地圖。

繼續閱讀