• 如何通过华为定位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”。
    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…

    原作者:胡椒

  • 相关阅读:
    springcloud生态图
    redis持久化机制之AOF与RDB
    关键字的理解
    Java IO6 :IO总结
    Java IO5:管道流、对象流
    Java IO4:字符流进阶及BufferedWriter、BufferedReader
    Java IO3:字节流
    Java IO2:RandomAccessFile
    Java IO1:IO和File
    java学习笔记
  • 原文地址:https://www.cnblogs.com/developer-huawei/p/14892305.html
Copyright © 2020-2023  润新知