如何通過華為定位API精準獲取使用者所在地理位置?
我們在外出旅行時,通常需要在酒店App中預訂酒店。那麼,在酒店App中是如何獲取使用者地理位置資訊從而實現“附近的酒店”的功能查詢?為此,我開發了一款名為Hotel Booking的應用。
本文中,我將整合定位服務,並介紹如何使用getLastlocation和getLocationWithAddress方法、如何使用回撥方法,以及如何在Flutter中將資料儲存到應用中的Shared Preferences。
-
定位服務
定位服務幫助開發者的應用快速準確地獲取使用者的位置,並通過GPS、Wi-Fi以及基站定位能力來擴充套件其全球定位能力。
融合定位:提供一套簡單易用的API,以便您基於GPS、Wi-Fi以及基站位置資料來快速獲取使用者裝置位置。
活動識別:通過加速度感測器、蜂窩網路資訊以及磁力儀等識別使用者的活動狀態,幫助您根據使用者行為調整應用。
地理圍欄:您可以通過API來設定一個感興趣的區域,以便在特定的動作(例如離開、進入或者逗留在該區域)發生時,您的應用可以接收到通知。
軟體要求
1.Android Studio 3.X
2.JDK 1.8及以上
3.SDK Platform 19及以上
4.Gradle 4.6及以上
整合步驟
1.在AppGallery Connect中註冊華為開發者賬號。
2.參考“建立您的AGC專案”和“在專案下新增應用”章節建立應用。
3.根據當前位置來設定資料處理位置。
4.開通所需服務:華為定位服務。
5.生成簽名證書指紋。
6.配置簽名證書指紋。
7.將您的agconnect-services.json檔案拷貝到您的應用級根目錄下。
重要:新增應用時,輸入的應用包名應與您的Flutter專案包名一致。
注意:下載agconnect-services.json檔案前,確保已開啟所需的HMS服務。
開發流程
在Android Studio中建立應用。
1.建立Flutter專案。
2.新增編譯依賴。
a)應用級Gradle依賴:
在專案中選擇“Android>app>build.gradle”。 applyplugin:'com.android.application'applyplugin:'com.huawei.agconnect'
b)專案級Gradle依賴:
maven{url'https://developer.huawei.com/repo/'} classpath'com.huawei.agconnect:agcp:1.4.1.300'
在AndroidManifest.xml檔案中新增如下許可權:
<uses-permissionandroid:name="android.permission.INTERNET"/> <uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permissionandroid:name="android.permission.ACCESS_BACKGROUND_LOCATION"/> <uses-permissionandroid:name="android.permission.ACTIVITY_RECOGNITION"/> <uses-permissionandroid:name="com.huawei.hms.permission.ACTIVITY_RECOGNITION"/>
3.參考連結下載所需的跨平臺外掛。
4.完成上述所有步驟後,在pubspec.yaml檔案中新增對所需的HMS服務對應的Flutter外掛的依賴。您可在pub.dev中找到最新版本的外掛。
dependencies: flutter: sdk:flutter shared_preferences:^0.5.12+4 bottom_navy_bar:^5.6.0 cupertino_icons:^1.0.0 provider:^4.3.3 huawei_location: path:../huawei_location/ flutter: uses-material-design:true assets: -assets/images/
5.新增後,執行flutter pub get命令。至此,所有的外掛已準備就緒。
6.開啟main.dart檔案來建立UI和業務邏輯。
整合定位服務
許可權
首先,應用需要有訪問位置資料和物理資料的許可權。
建立PermissionHandler例項,並呼叫initState()方法來初始化例項。
finalPermissionHandlerpermissionHandler; @override voidinitState(){ permissionHandler=PermissionHandler();super.initState(); }
檢查許可權
呼叫hasLocationPermission()方法來檢查裝置是否有所需的許可權。
voidhasPermission()async{ try{ finalboolstatus=awaitpermissionHandler.hasLocationPermission(); if(status==true){ showToast("Haspermission:$status"); }else{ requestPermission(); } }onPlatformExceptioncatch(e){ showToast(e.toString()); } }
如果裝置沒有所需許可權,呼叫requestLocationPermission()方法來申請相關許可權。
voidrequestPermission()async{ try{ finalboolstatus=awaitpermissionHandler.requestLocationPermission(); showToast("Ispermissiongranted"); }onPlatformExceptioncatch(e){ showToast(e.toString()); } }
-
融合定位
使用init()方法建立FusedLocationPrvoiderClient例項,然後使用該例項呼叫定位API。
finalFusedLocationProviderClientlocationService @override voidinitState(){ locationService=FusedLocationProviderClient();super.initState(); }
位置更新事件
呼叫onLocationData()方法來偵聽位置更新事件。
StreamSubscription<Location>streamSubscription @override voidinitState(){ streamSubscription=locationService.onLocationData.listen((location){});super.initState(); }
getLastLocation()
voidgetLastLocation()async{ try{ Locationlocation=awaitlocationService.getLastLocation(); setState((){ lastlocation=location.toString(); print("print:"+lastlocation); }); }catch(e){ setState((){ print("error:"+e.toString()); }); } }
getLastLocationWithAddress()
建立LocationRequest例項,並設定相關引數。
finalLocationRequestlocationRequest; locationRequest=LocationRequest() ..needAddress=true ..interval=5000; void_getLastLocationWithAddress()async{ try{ HWLocationlocation= awaitlocationService.getLastLocationWithAddress(locationRequest); setState((){ Stringstreet=location.street; Stringcity=location.city; Stringcountryname=location.countryName; currentAddress='$street'+','+'$city'+','+'$countryname'; print("res:$location"); }); showToast(currentAddress); }onPlatformExceptioncatch(e){ showToast(e.toString()); } }
通過Callback進行位置更新
建立LocationCallback例項,並在initstate()中建立回撥函式。
LocationCallbacklocationCallback; @override voidinitState(){ locationCallback=LocationCallback( onLocationResult:_onCallbackResult, onLocationAvailability:_onCallbackResult, ); super.initState(); } voidrequestLocationUpdatesCallback()async{ if(_callbackId==null){ try{ finalintcallbackId=awaitlocationService.requestLocationUpdatesExCb( locationRequest,locationCallback); _callbackId=callbackId; }onPlatformExceptioncatch(e){ showToast(e.toString()); } }else{ showToast("Alreadyrequestedlocationupdates."); } } voidonCallbackResult(result){ print(result.toString()); showToast(result.toString()); }
我建立了一個Helper類,用於通過Shared Preferences在本地儲存使用者登入資訊。
classStorageUtil{ staticStorageUtil_storageUtil; staticSharedPreferences_preferences; staticFuture<StorageUtil>getInstance()async{ if(_storageUtil==null){ varsecureStorage=StorageUtil._(); awaitsecureStorage._init(); _storageUtil=secureStorage; } return_storageUtil; } StorageUtil._(); Future_init()async{ _preferences=awaitSharedPreferences.getInstance(); } //getstring staticStringgetString(Stringkey){ if(_preferences==null)returnnull; Stringresult=_preferences.getString(key)??null; print('result,$result'); returnresult; } //putstring staticFuture<void>putString(Stringkey,Stringvalue){ if(_preferences==null)returnnull; print('result$value'); return_preferences.setString(key,value); } }
結果
溫馨提示
1.請下載最新版本的HMS服務Flutter外掛。
2.如需使用模擬位置功能,需要在AndroidManifest.xml檔案中新增相關許可權。
3.如需更新外掛,可點選pug get按鈕。
欲瞭解HMS Core更多詳情,請參閱:
>>華為開發者聯盟官網
>>獲取開發指導文件
>>參與開發者討論請到CSDN社群或者Reddit社群
>>下載demo和示例程式碼請到Github或者Gitee
>>解決整合問題請到Stack Overflow
原文連結:developer.huawei.com/consumer/cn…
原作者:胡椒