我們在外出旅行時,通常需要在酒店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”。 apply plugin: 'com.android.application' apply plugin: 'com.huawei.agconnect'
b) 項目級Gradle依賴:
maven {url 'https://developer.huawei.com/repo/'} classpath 'com.huawei.agconnect:agcp:1.4.1.300'
在AndroidManifest.xml文件中添加如下權限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" /> <uses-permission android: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()方法來初始化實例。
final PermissionHandler permissionHandler; @override void initState() { permissionHandler = PermissionHandler(); super.initState(); }
檢查權限
調用hasLocationPermission()方法來檢查設備是否有所需的權限。
void hasPermission() async { try { final bool status = await permissionHandler.hasLocationPermission(); if(status == true){ showToast("Has permission: $status"); }else{ requestPermission(); } } on PlatformException catch (e) { showToast(e.toString()); } }
如果設備沒有所需權限,調用requestLocationPermission()方法來申請相關權限。
void requestPermission() async { try { final bool status = await permissionHandler.requestLocationPermission(); showToast("Is permission granted"); } on PlatformException catch (e) { showToast(e.toString()); } }
-
融合定位
使用init()方法創建FusedLocationPrvoiderClient實例,然后使用該實例調用定位API。
final FusedLocationProviderClient locationService @override void initState() { locationService = FusedLocationProviderClient(); super.initState(); }
位置更新事件
調用onLocationData()方法來偵聽位置更新事件。
StreamSubscription<Location> streamSubscription @override void initState() { streamSubscription = locationService.onLocationData.listen((location) {});super.initState(); }
getLastLocation()
void getLastLocation() async { try { Location location = await locationService.getLastLocation(); setState(() { lastlocation = location.toString(); print("print: " + lastlocation); }); } catch (e) { setState(() { print("error: " + e.toString()); }); } }
getLastLocationWithAddress()
創建LocationRequest實例,並設置相關參數。
final LocationRequest locationRequest; locationRequest = LocationRequest() ..needAddress = true ..interval = 5000; void _getLastLocationWithAddress() async { try { HWLocation location = await locationService.getLastLocationWithAddress(locationRequest); setState(() { String street = location.street; String city = location.city; String countryname = location.countryName; currentAddress = '$street' + ',' + '$city' + ' , ' + '$countryname'; print("res: $location"); }); showToast(currentAddress); } on PlatformException catch (e) { showToast(e.toString()); } }
通過Callback進行位置更新
創建LocationCallback實例,並在initstate()中創建回調函數。
LocationCallback locationCallback; @override void initState() { locationCallback = LocationCallback( onLocationResult: _onCallbackResult, onLocationAvailability: _onCallbackResult, ); super.initState(); } void requestLocationUpdatesCallback() async { if (_callbackId == null) { try { final int callbackId = await locationService.requestLocationUpdatesExCb( locationRequest, locationCallback); _callbackId = callbackId; } on PlatformException catch (e) { showToast(e.toString()); } } else { showToast("Already requested location updates."); } } void onCallbackResult(result) { print(result.toString()); showToast(result.toString()); }
我創建了一個Helper類,用於通過Shared Preferences在本地存儲用戶登錄信息。
class StorageUtil { static StorageUtil _storageUtil; static SharedPreferences _preferences; static Future<StorageUtil> getInstance() async { if (_storageUtil == null) { var secureStorage = StorageUtil._(); await secureStorage._init(); _storageUtil = secureStorage; } return _storageUtil; } StorageUtil._(); Future _init() async { _preferences = await SharedPreferences.getInstance(); } // get string static String getString(String key) { if (_preferences == null) return null; String result = _preferences.getString(key) ?? null; print('result,$result'); return result; } // put string static Future<void> putString(String key, String value) { if (_preferences == null) return null; 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…
原作者:胡椒