Flutter位置服务插件at_location_flutter的使用

发布于 1周前 作者 caililin 来自 Flutter

Flutter位置服务插件 at_location_flutter 的使用

at_location_flutter 是一个用于在Flutter应用中实现位置共享功能的插件。它允许两个atsign之间共享和接收位置信息,基于去中心化的atPlatform模型,提供端到端加密等特性。

概述

该插件支持以下特性:

  • 通过个人数据存储进行数据访问的加密控制
  • 不需要应用程序后端
  • 端到端加密,只有数据所有者拥有密钥
  • 私有且无监控的连接
  • 共享位置并在地图上查看

更多关于atPlatform的工作原理,请参考 官方文档

快速开始

1. 使用 at_app 创建示例应用

$ flutter pub global activate at_app 
$ at_app create --sample=<package ID> <app name>
$ cd <app name>
$ flutter run

注意:

  • 你只需要运行一次 flutter pub global activate
  • Windows用户请使用 at_app.bat

2. 从GitHub克隆源码

可以从 GitHub仓库 克隆源码。

$ git clone https://github.com/atsign-foundation/at_widgets.git

3. 手动添加包到项目

可以按照 pub.dev 上的说明手动添加包。

设置与初始化

初始化

首先需要通过Onboarding widget对atsign进行身份验证,然后初始化位置服务:

await initializeLocationService(
  navKey,
  mapKey: 'xxxx', // 替换为你的MapTiler API key
  apiKey: 'xxxx', // 替换为你的HERE API key
  showDialogBox: true,
  streamAlternative: (__){},
  isEventInUse: true, 
);

权限设置

iOS: 在 ios/Runner/Info.plist 中添加:

<key>NSLocationWhenInUseUsageDescription</key>
<string>Explain the description here.</string>

Android: 在 android/app/src/main/AndroidManifest.xml 中添加:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

使用方法

分享位置

分享位置给某个atsign 30分钟:

sendShareLocationNotification(receiver, 30);

请求位置

向某个atsign请求位置:

sendRequestLocationNotification(receiver);

查看位置

查看多个atsign的位置:

AtLocationFlutterPlugin(
  ['atsign1', 'atsign2', ...]
)

使用默认地图视图

Navigator.push(
      context,
      MaterialPageRoute(
          builder: (context) => MapScreen(
                currentAtSign: AtLocationNotificationListener().currentAtSign,
                userListenerKeyword: locationNotificationModel,
              )),
    );

使用默认主页视图

Navigator.push(
      context,
      MaterialPageRoute(
        builder: (BuildContext context) => HomeScreen(),
    ));

数据类型

  • LocationNotificationModel: 包含共享或请求位置的详细信息。
  • LocationDataModel: 包含实际地理位置和其他详细信息。
  • KeyLocationModel: 用于跟踪所有共享或请求通知。

获取API Keys

获取Map Key

  1. 访问 MapTiler
  2. 登录或创建免费账户
  3. 返回 MapTiler
  4. 复制嵌入式查看器中的key(例如:https://api.maptiler.com/maps/streets/?key=YOUR_MAP_KEY#-0.1/-2.80318/-38.08702
  5. YOUR_MAP_KEY 替换并使用

获取API Key

访问 HERE开发者指南 并按照步骤获取API Key。

示例代码

以下是一个完整的示例代码,展示了如何使用 at_location_flutter 插件:

import 'dart:async';
import 'package:at_app_flutter/at_app_flutter.dart' show AtEnv;
import 'package:at_client_mobile/at_client_mobile.dart';
import 'package:at_onboarding_flutter/at_onboarding_flutter.dart'
    show AtOnboarding, AtOnboardingConfig, AtOnboardingResultStatus;
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart' show getApplicationSupportDirectory;

Future<void> main() async {
  await AtEnv.load();
  runApp(const MyApp());
}

Future<AtClientPreference> loadAtClientPreference() async {
  var dir = await getApplicationSupportDirectory();
  return AtClientPreference()
        ..rootDomain = AtEnv.rootDomain
        ..namespace = AtEnv.appNamespace
        ..hiveStoragePath = dir.path
        ..commitLogPath = dir.path
        ..isLocalStoreRequired = true;
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Future<AtClientPreference> futurePreference = loadAtClientPreference();
  AtClientPreference? atClientPreference;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: NavService.navKey,
      theme: ThemeData().copyWith(
        brightness: Brightness.light,
        primaryColor: const Color(0xFFf4533d),
        colorScheme: ThemeData.light().colorScheme.copyWith(
              primary: const Color(0xFFf4533d),
            ),
        bottomAppBarTheme: const BottomAppBarTheme(color: Colors.white),
        scaffoldBackgroundColor: Colors.white,
      ),
      darkTheme: ThemeData().copyWith(
        brightness: Brightness.dark,
        primaryColor: Colors.blue,
        colorScheme: ThemeData.dark().colorScheme.copyWith(
              primary: Colors.blue,
            ),
        bottomAppBarTheme: BottomAppBarTheme(color: Colors.grey[850]),
        scaffoldBackgroundColor: Colors.grey[850],
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('at_location example'),
          actions: <Widget>[
            IconButton(
              onPressed: () {},
              icon: Icon(
                Theme.of(context).brightness == Brightness.light
                    ? Icons.dark_mode_outlined
                    : Icons.light_mode_outlined,
              ),
            )
          ],
        ),
        body: Builder(
          builder: (context) => Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () async {
                    var preference = await futurePreference;
                    setState(() {
                      atClientPreference = preference;
                    });
                    final result = await AtOnboarding.onboard(
                      context: context,
                      config: AtOnboardingConfig(
                        atClientPreference: atClientPreference!,
                        domain: AtEnv.rootDomain,
                        rootEnvironment: AtEnv.rootEnvironment,
                        appAPIKey: AtEnv.appApiKey,
                      ),
                    );
                    if (result.status == AtOnboardingResultStatus.success) {
                      Navigator.push(context, MaterialPageRoute(builder: (_) => const SecondScreen()));
                    }
                  },
                  child: const Text('Onboard an atSign'),
                ),
                const SizedBox(height: 10),
                ElevatedButton(
                  onPressed: () async {
                    var preference = await futurePreference;
                    atClientPreference = preference;
                    AtOnboarding.reset(
                      context: context,
                      config: AtOnboardingConfig(
                        atClientPreference: atClientPreference!,
                        domain: AtEnv.rootDomain,
                        rootEnvironment: AtEnv.rootEnvironment,
                        appAPIKey: AtEnv.appApiKey,
                      ),
                    );
                  },
                  child: const Text('Reset'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class NavService {
  static GlobalKey<NavigatorState> navKey = GlobalKey();
}

更多关于Flutter位置服务插件at_location_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter位置服务插件at_location_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何使用 at_location_flutter 插件的示例代码。这个插件可以帮助你在Flutter应用中获取设备的位置信息。

首先,确保你已经在 pubspec.yaml 文件中添加了 at_location_flutter 依赖:

dependencies:
  flutter:
    sdk: flutter
  at_location_flutter: ^最新版本号  # 请替换为实际的最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来,在你的Flutter应用中,你可以按照以下步骤使用 at_location_flutter 插件来获取位置信息。

1. 导入必要的包

在你的 Dart 文件中导入 at_location_flutter 包:

import 'package:at_location_flutter/at_location_flutter.dart';
import 'package:flutter/material.dart';

2. 配置权限

AndroidManifest.xml 中添加必要的权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

对于iOS,你需要在 Info.plist 中添加以下权限:

<key>NSLocationWhenInUseUsageDescription</key>
<string>App needs access to location when in use</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>App needs access to location always</string>

3. 请求位置权限并获取位置信息

下面是一个完整的示例,展示了如何请求位置权限并获取当前位置信息:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LocationScreen(),
    );
  }
}

class LocationScreen extends StatefulWidget {
  @override
  _LocationScreenState createState() => _LocationScreenState();
}

class _LocationScreenState extends State<LocationScreen> {
  AtLocationFlutter? _locationPlugin;
  Position? _currentPosition;

  @override
  void initState() {
    super.initState();
    _locationPlugin = AtLocationFlutter();
    _requestLocationPermission();
  }

  Future<void> _requestLocationPermission() async {
    bool serviceEnabled;
    LocationPermission permission;

    // Test if location services are enabled.
    serviceEnabled = await _locationPlugin!.isLocationServiceEnabled();
    if (!serviceEnabled) {
      return Future.error('Location services are disabled.');
    }

    permission = await _locationPlugin!.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await _locationPlugin!.requestPermission();
      if (permission == LocationPermission.deniedForever) {
        // Permissions are permanently denied, we cannot request permissions anymore.
        return Future.error(
            'Location permissions are permanently denied, we cannot request permissions.');
      }
    }

    if (permission == LocationPermission.denied) {
      return Future.error('Location permissions are denied');
    }

    _getCurrentLocation();
  }

  Future<void> _getCurrentLocation() async {
    try {
      Position position = await _locationPlugin!.getCurrentPosition(
          desiredAccuracy: LocationAccuracy.high);
      setState(() {
        _currentPosition = position;
      });
    } catch (e) {
      print(e);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Location Example'),
      ),
      body: Center(
        child: _currentPosition == null
            ? CircularProgressIndicator()
            : Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('Latitude: ${_currentPosition!.latitude}'),
                  Text('Longitude: ${_currentPosition!.longitude}'),
                ],
              ),
      ),
    );
  }
}

在这个示例中,我们首先检查位置服务是否启用,然后请求位置权限。如果权限被授予,我们将获取当前位置并在UI中显示。

请注意,在实际应用中,你应该处理更多的错误情况,并根据需要调整位置请求的精度和频率。此外,对于生产环境中的应用,请确保遵循相关的隐私政策和最佳实践。

回到顶部