Flutter位置追踪插件flutter_radar的使用

Flutter位置追踪插件flutter_radar的使用

Radar 是一个领先的地理围栏和位置跟踪平台。通过 Radar SDK,您可以轻松地为应用程序添加地理围栏、位置跟踪、行程跟踪、地理编码和搜索功能。

文档

示例代码

以下是一个完整的示例应用,展示了如何在 Flutter 中使用 flutter_radar 插件进行位置跟踪和相关操作。

完整示例 Demo

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter_radar/flutter_radar.dart';
import 'package:permission_handler/permission_handler.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  final ButtonStyle raisedButtonStyle = ElevatedButton.styleFrom(
    minimumSize: Size(88, 36),
    padding: EdgeInsets.symmetric(horizontal: 16),
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(2)),
    ),
  );

  [@override](/user/override)
  void initState() {
    super.initState();
    initRadar();
  }

  [@override](/user/override)
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.inactive) {
      Radar.logResigningActive();
    } else if (state == AppLifecycleState.paused) {
      Radar.logBackgrounding();
    }
  }

  // 静态回调函数
  [@pragma](/user/pragma)('vm:entry-point')
  static void onLocation(Map res) {
    print('📍📍 onLocation: $res');
  }

  [@pragma](/user/pragma)('vm:entry-point')
  static void onClientLocation(Map res) {
    print('📍📍 onClientLocation: $res');
  }

  [@pragma](/user/pragma)('vm:entry-point')
  static void onError(Map res) {
    print('📍📍 onError: $res');
  }

  [@pragma](/user/pragma)('vm:entry-point')
  static void onLog(Map res) {
    print('📍📍 onLog: $res');
  }

  [@pragma](/user/pragma)('vm:entry-point')
  static void onEvents(Map res) {
    print('📍📍 onEvents: $res');
  }

  [@pragma](/user/pragma)('vm:entry-point')
  static void onToken(Map res) {
    print('📍📍 onToken: $res');
  }

  Future<void> initRadar() async {
    // 初始化 Radar SDK
    Radar.initialize('prj_test_pk_0000000000000000000000000000000000000000');
    Radar.setUserId('flutter');
    Radar.setDescription('Flutter');
    Radar.setMetadata({'foo': 'bar', 'bax': true, 'qux': 1});
    Radar.setLogLevel('info');
    Radar.setAnonymousTrackingEnabled(false);

    // 设置回调函数
    Radar.onLocation(onLocation);
    Radar.onClientLocation(onClientLocation);
    Radar.onError(onError);
    Radar.onEvents(onEvents);
    Radar.onLog(onLog);
    Radar.onToken(onToken);

    // 请求权限
    await Radar.requestPermissions(false);
    await Radar.requestPermissions(true);

    var permissionStatus = await Radar.getPermissionsStatus();
    if (permissionStatus != "DENIED") {
      var b = await Radar.startTrackingCustom({
        ...Radar.presetResponsive,
        "showBlueBar": true,
      });
      var c = await Radar.getTrackingOptions();
      print("Tracking options $c");
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('flutter_radar_example'),
        ),
        body: SingleChildScrollView(
          scrollDirection: Axis.vertical,
          child: Container(
            child: Column(children: [
              Permissions(),
              TrackOnce(),
              ElevatedButton(
                style: raisedButtonStyle,
                onPressed: () async {
                  var status = await Radar.requestPermissions(false);
                  print(status);
                  if (status == 'GRANTED_FOREGROUND') {
                    status = await Radar.requestPermissions(true);
                    print(status);
                  }
                },
                child: Text('requestPermissions()'),
              ),
              ElevatedButton(
                style: raisedButtonStyle,
                onPressed: () async {
                  PermissionStatus status = await Permission.activityRecognition.request();
                  if (status.isGranted) {
                    print('Permission granted');
                  } else {
                    print('Permission denied');
                  }
                },
                child: Text('request activity permissions'),
              ),
              ElevatedButton(
                style: raisedButtonStyle,
                onPressed: () async {
                  Radar.setForegroundServiceOptions({
                    'title': 'Tracking',
                    'text': 'Trip tracking started',
                    'icon': 2131165271,
                    'importance': 2,
                    'updatesOnly': false,
                    'activity': 'io.radar.example.MainActivity'
                  });
                  var resp = await Radar.startTrip(
                    tripOptions: {
                      "externalId": '299',
                      "destinationGeofenceTag": 'store',
                      "destinationGeofenceExternalId": '123',
                      "mode": 'car',
                      "scheduledArrivalAt": "2020-08-20T10:30:55.837Z",
                      "metadata": {"test": 123}
                    },
                    trackingOptions: {
                      "desiredStoppedUpdateInterval": 30,
                      "fastestStoppedUpdateInterval": 30,
                      "desiredMovingUpdateInterval": 30,
                      "fastestMovingUpdateInterval": 30,
                      "desiredSyncInterval": 20,
                      "desiredAccuracy": "high",
                      "stopDuration": 0,
                      "stopDistance": 0,
                      "replay": "none",
                      "sync": "all",
                      "showBlueBar": true,
                      "useStoppedGeofence": false,
                      "stoppedGeofenceRadius": 0,
                      "useMovingGeofence": false,
                      "movingGeofenceRadius": 0,
                      "syncGeofences": false,
                      "syncGeofencesLimit": 0,
                      "beacons": false,
                      "foregroundServiceEnabled": true
                    }
                  );
                  print("startTrip: $resp");
                },
                child: Text('startTrip'),
              ),
              // 其他按钮...
            ]),
          ),
        ),
      ),
    );
  }
}

// 权限状态显示组件
class Permissions extends StatefulWidget {
  [@override](/user/override)
  _PermissionsState createState() => _PermissionsState();
}

class _PermissionsState extends State<Permissions> {
  String? _status = 'NOT_DETERMINED';
  final ButtonStyle raisedButtonStyle = ElevatedButton.styleFrom(
    minimumSize: Size(88, 36),
    padding: EdgeInsets.symmetric(horizontal: 16),
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(2)),
    ),
  );

  [@override](/user/override)
  void initState() {
    super.initState();
    _getPermissionsStatus();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text(
          '$_status',
          style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
        ),
        ElevatedButton(
          style: raisedButtonStyle,
          child: Text('getPermissionsStatus()'),
          onPressed: () {
            _getPermissionsStatus();
          },
        ),
      ],
    );
  }

  Future _getPermissionsStatus() async {
    String? status = await Radar.getPermissionsStatus();
    setState(() {
      _status = status;
    });
  }
}

// 跟踪一次位置组件
class TrackOnce extends StatefulWidget {
  [@override](/user/override)
  _TrackOnceState createState() => _TrackOnceState();
}

class _TrackOnceState extends State<TrackOnce> {
  final ButtonStyle raisedButtonStyle = ElevatedButton.styleFrom(
    minimumSize: Size(88, 36),
    padding: EdgeInsets.symmetric(horizontal: 16),
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(2)),
    ),
  );

  [@override](/user/override)
  Widget build(BuildContext context) {
    return ElevatedButton(
      child: Text('trackOnce()'),
      style: raisedButtonStyle,
      onPressed: () {
        _showTrackOnceDialog();
      },
    );
  }

  Future<void> _showTrackOnceDialog() async {
    var trackResponse = await Radar.trackOnce();
    print("trackResponse: $trackResponse");

    Widget okButton = TextButton(
      child: Text('OK'),
      onPressed: () {
        Navigator.pop(context);
      },
    );

    AlertDialog alert = AlertDialog(
      title: Text('flutter_radar_example'),
      content: Text(trackResponse?['status'] ?? ''),
      actions: [
        okButton,
      ],
    );

    showDialog(
      context: context,
      builder: (BuildContext context) {
        return alert;
      },
    );
  }
}

// 显示对话框
showAlertDialog(BuildContext context, String text) {
  Widget okButton = TextButton(
    child: Text('OK'),
    onPressed: () {
      Navigator.of(context).pop();
    },
  );

  AlertDialog alert = AlertDialog(
    title: Text('flutter_radar_example'),
    content: Text(text),
    actions: [
      okButton,
    ],
  );

  showDialog(
    context: context,
    builder: (BuildContext context) {
      return alert;
    },
  );
}

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

1 回复

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


当然,以下是一个关于如何在Flutter应用中使用flutter_radar插件来实现位置追踪的代码示例。请注意,flutter_radar是一个假想的插件名称,因为实际中并没有一个名为flutter_radar的广泛认可的位置追踪插件。不过,大多数位置追踪插件的使用方式类似,这里我会以一个假设的flutter_radar插件为例进行说明。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加flutter_radar插件的依赖。

dependencies:
  flutter:
    sdk: flutter
  flutter_radar: ^x.y.z  # 假设的版本号

然后运行flutter pub get来安装依赖。

2. 配置权限

由于位置追踪需要访问设备的GPS,你需要在AndroidManifest.xmlInfo.plist中添加必要的权限。

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" />

iOS

ios/Runner/Info.plist中添加:

<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location when in use.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when in use.</string>

3. 使用插件

在你的Flutter代码中,你可以这样使用flutter_radar插件来追踪位置。

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

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

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

class LocationTracker extends StatefulWidget {
  @override
  _LocationTrackerState createState() => _LocationTrackerState();
}

class _LocationTrackerState extends State<LocationTracker> {
  late FlutterRadar _flutterRadar;
  late Position? _currentPosition;

  @override
  void initState() {
    super.initState();
    _flutterRadar = FlutterRadar();
    _startLocationTracking();
  }

  void _startLocationTracking() async {
    try {
      bool hasPermission = await _flutterRadar.requestLocationPermission();
      if (hasPermission) {
        _flutterRadar.startLocationUpdates(onLocationChanged: (position) {
          setState(() {
            _currentPosition = position;
          });
        });
      } else {
        print("Location permission denied");
      }
    } catch (e) {
      print("Error starting location tracking: $e");
    }
  }

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

  @override
  void dispose() {
    _flutterRadar.stopLocationUpdates();
    super.dispose();
  }
}

注意

  1. 权限请求:在实际应用中,你应该在UI中优雅地请求权限,并在用户拒绝时提供说明或引导用户去设置中开启权限。
  2. 后台追踪:如果需要后台追踪,你需要配置更多的后台权限和代码逻辑。
  3. 错误处理:应该添加更多的错误处理逻辑来应对各种可能的异常情况。
  4. 插件文档:实际使用时,请查阅flutter_radar(或你实际使用的插件)的官方文档,因为不同插件的API和配置方式可能有所不同。

由于flutter_radar是一个假想的插件名称,你需要将上述代码中的flutter_radar替换为你实际使用的位置追踪插件的名称,并参考该插件的官方文档进行具体实现。

回到顶部