出行品類HarmonyOS高德地圖集成過程分享
項目背景
電動車因騎行方便、節省時間等優勢,成為我們日常出行的交通工具之一,國內電動車的需求數據龐大且逐年攀升。然而電動車頻繁被盜也不是新聞了,不僅給用戶帶來煩惱,也給警務工作增加負擔。如何制定一套提升用戶體驗又能兼顧高安全性的出行品類解決方案,是我們主要思考研究的方向。
為了提升及改善日常出行品類的用戶體驗,讓手機成為電動車鑰匙無感解鎖,我們想到可利用藍牙靠近發現的特性,采用無鑰匙解鎖控車作為主要功能,實現設備快速連接。但是常見的電動車、童車等出行類產品均在戶外使用,其安全性要求極高,雖然可利用藍牙技術進行極簡連接控制,但由于藍牙本身具有開放廣播的特性,在設備附近的人都可以通過手機發現設備,則會帶來嚴重的安全隱患。
針對此問題,經過反復推敲,最終決定利用安全秘鑰結合云服務,在設備發現、連接操控進行嚴格的操作認證管控,實現極簡連接體驗和嚴格安全控車需求;結合GPS、電子地圖,實現設備的出行軌跡展示功能,動態計算設備的停留點、停留時間;采用出行產品電子圍欄技術,用戶通過手機直接在電子地圖上圈定范圍區域,如果設備被移到范圍外,手機就會收到報警通知,防止車輛丟失。
邏輯實現
手機靠近電動車設備,手機藍牙打開在未連接的情況下,手機將彈出連接提示,連接后將跳轉至App,可綁定設備以及查看相關狀態,綁定后通過手機一鍵控制開關。設定自動鎖車的時間,超過設定的時間限制,設備將會自動下電并設防。設置電子圍欄,下電設防之后,防盜報警裝置啟動,超出區域報警提示。
以下為App部分效果圖:
電子地圖采用高德地圖,接下來我們看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承載。
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()方法銷毀地圖。