我的應用所需權限都已全部打開,定位數據依然不準確?
近期華為開發者論壇有收到開發者提問:我的應用app需要調用GPS的位置服務,已經將應用所需要的所有權限全部打開,而且使用了wifi和4G網絡,手機的耗電管理和聯網管理等設置也全部為app開放,但使用標準Android接口調用的GPS位置和速度數據依然非常不準確,怎麼解決呢?問題鏈接
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定位產生功耗。
如何持續獲取位置信息?
如果希望應用可以持續獲取設備位置,可以使用定位服務提供的requestLocationUpdates()
接口。該接口根據入參形式的不同,將以兩種不同的形式將位置信息返回。一種是通過調用已經定義的LocationCallback
類中onLocationResult()
回調方法返回一個包含位置信息的LocationResult
對象,另一種是將位置信息置於PendingIntent擴展信息中返回。
當應用程序不再需要接收位置更新時,應當停止位置更新,以便於降低功耗。要停止位置更新,可以調用removeLocationUpdates()
,傳入與requestLocationUpdates()
接口相對應的LocationCallback
或PendingIntent對象。這裡以回調方式作為樣例,代碼如下。詳細的參數說明請參見LocationService
接口說明。
1.設置持續定位請求參數。
LocationRequest mLocationRequest = new LocationRequest(); // 設置位置更新的間隔(單位為毫秒) mLocationRequest .setInterval(10000 ); // 設置定位類型 mLocationRequest .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
- 定義位置更新回調。
LocationCallback mLocationCallback ; mLocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult ) { if ( locationResult != null) { // 處理位置回調結果 } } };
- 調用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) { // 接口調用失敗的處理 } });
- 調用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) { // ... } });
欲了解更多詳情,請參閱:
華為定位服務官網: //developer.huawei.com/consumer/cn/hms/huawei-locationkit?ha_source=hms1
示例代碼://github.com/HMS-Core/hms-location-demo
原文鏈接://developer.huawei.com/consumer/cn/forum/topic/0202524842524900621?fid=18
原作者:胡椒