我的應用所需許可權都已全部開啟,定位資料依然不準確?

華為開發者論壇發表於2021-04-17

近期華為開發者論壇有收到開發者提問:我的應用app需要呼叫GPS的位置服務,已經將應用所需要的所有許可權全部開啟,而且使用了wifi和4G網路,手機的耗電管理和聯網管理等設定也全部為app開放,但使用標準Android介面呼叫的GPS位置和速度資料依然非常不準確,怎麼解決呢?問題連結
image
Android原生定位優缺點分析
提問的開發者在應用中呼叫的是Android原生的介面進行定位。

Android原生定位提供GPS定位和網路定位兩種模式。GPS定位支援離線定位,依靠衛星,沒有網路也能定位,精度高,但功耗大,因需要開啟移動裝置中的GPS定位模組,會消耗較多電量;蒐集衛星、計算資料工作比較耗時,通常導致初次定位較慢;且由於需要接收衛星訊號,易受環境、地理位置影響,即訊號的接收容易受天氣,以及建築等遮擋物的影響,隧道、山區等地訊號通常較差,高聳的建築物、密集的樓房、屋頂、牆壁,都會影響GPS接收訊號導致定位不準。

Network定位(網路定位),定位速度快,只要具備網路或者基站要求,在任何地方都可實現瞬間定位,室內同樣滿足;功耗小,耗電量小;但定位精度差,容易受干擾,在基站或者WiFi數量少、訊號弱的地方定位質量較差,或者無法定位;必須連線網路才能實現定位。

上述的兩種定位模式都有各自的優缺點,提問的開發者在應用中呼叫Android原生的介面進行定位,傳統的GPS定位精度只有3-7米,而我國城市主幹道單一車道寬一般是3.75米,也就是說GPS無法做到車道線級定位。尤其在城市道路或峽谷中,精度會進一步下降。

那麼除了呼叫原生的介面獲取定位以外,還有其他解決辦法嗎?

華為定位服務
華為定位服務(Location Kit)是華為為開發者提供的一項定位能力。採用衛星導航系統(Global Navigation Satellite System,簡稱GNSS)、Wi-Fi、基站等多途徑的混合定位模式進行定位,應用可快速、精準地獲取使用者位置資訊。

當前華為定位服務提供的主要能力包含三個部分:融合定位、活動識別和地理圍欄。開發者可以根據自己的需求,呼叫相應的能力。

其中活動識別功能通過加速度感測器、蜂窩網路資訊、磁力計識別使用者運動狀態,便於通過了解使用者行為來調整應用。地理圍欄功能可以通過API設定感興趣的位置區域,在指定操作(如離開、進入、駐留)發生時,手機即可及時收到一個通知。融合定位功能結合GNSS、Wi-Fi和基站位置資料,提供一套簡單易用的API,可以更方便快速獲取裝置位置資訊,實現精準定位。

融合定位:基於多用途的融合定位,實現精準定位
隨著5G通訊技術的開展,融合定位技術融合了目前市面上的所有定位方式,包括GNSS、Wifi定位、基站定位、藍芽定位以及感測器定位,可謂定位技術集大成者。

GNSS在首次定位時,由於要重新獲取星曆資訊,搜星後才能進行定位。當GNSS訊號弱時,可以快速進行輔助定位,增加定位成功率,實現精準定位。且可以根據手機的電量去選擇合適的定位方式,在手機電量低時,避免GNSS定位產生功耗。

image

如何持續獲取位置資訊?
如果希望應用可以持續獲取裝置位置,可以使用定位服務提供的requestLocationUpdates()介面。該介面根據入參形式的不同,將以兩種不同的形式將位置資訊返回。一種是通過呼叫已經定義的LocationCallback類中onLocationResult()回撥方法返回一個包含位置資訊的LocationResult物件,另一種是將位置資訊置於PendingIntent擴充套件資訊中返回。

當應用程式不再需要接收位置更新時,應當停止位置更新,以便於降低功耗。要停止位置更新,可以呼叫removeLocationUpdates(),傳入與requestLocationUpdates()介面相對應的LocationCallback或PendingIntent物件。這裡以回撥方式作為樣例,程式碼如下。詳細的引數說明請參見LocationService介面說明。

1.設定持續定位請求引數。

LocationRequest mLocationRequest = new LocationRequest(); // 設定位置更新的間隔(單位為毫秒) mLocationRequest .setInterval(10000 ); // 設定定位型別 mLocationRequest .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

  1. 定義位置更新回撥。

LocationCallback mLocationCallback ; mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult ) { if ( locationResult != null) { // 處理位置回撥結果 } } };

  1. 呼叫requestLocationUpdates()進行持續定位。

fusedLocationProviderClient .requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper()) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { // 介面呼叫成功的處理 } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { // 介面呼叫失敗的處理 } });

  1. 呼叫removeLocationUpdates()停止位置更新。

// 注意:停止位置更新時,mLocationCallback必須與requestLocationUpdates方法中的LocationCallback引數為同一物件。 fusedLocationProviderClient.removeLocationUpdates(mLocationCallback) // 停止位置更新成功監聽回撥 .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { // ... } }) // 停止位置更新失敗監聽回撥 .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { // ... } });

image
欲瞭解更多詳情,請參閱:

華為定位服務官網: https://developer.huawei.com/consumer/cn/hms/huawei-locationkit?ha_source=hms1

定位服務開發指南:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides-V5/location-develop-steps-0000001050746143-V5?ha_source=hms1

示例程式碼:https://github.com/HMS-Core/hms-location-demo

原文連結:https://developer.huawei.com/consumer/cn/forum/topic/0202524842524900621?fid=18
原作者:胡椒

相關文章