-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmotiontag.dart
162 lines (136 loc) · 5.16 KB
/
motiontag.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'events/motiontag_event.dart';
import 'events/location_event.dart';
import 'events/started_event.dart';
import 'events/stopped_event.dart';
import 'events/transmission_error_event.dart';
import 'events/transmission_success_event.dart';
class MotionTag {
static final instance = MotionTag._();
final MethodChannel _channel = const MethodChannel('de.motiontag.tracker');
void Function(MotionTagEvent event)? _observer;
bool get _isAndroid => defaultTargetPlatform == TargetPlatform.android;
MotionTag._() {
_channel.setMethodCallHandler(_methodCallHandler);
}
/// Registers observer to receive [MotionTagEvent]
void setObserver(void Function(MotionTagEvent event)? observer) =>
_observer = observer;
/// Retrieves the current user token (JWT) or `null` if not specified yet.
Future<String?> getUserToken() async {
return await _channel.invokeMethod('getUserToken');
}
/// Updates the user token (JWT).
///
/// The SDK expects this function to be called before executing the [start] function, otherwise the collected data won't be able to be transmitted.
Future<void> setUserToken(String userToken) async {
await _channel.invokeMethod('setUserToken', {'userToken': userToken});
}
/// Retrieves the wifiOnlyDataTransfer value.
Future<bool> getWifiOnlyDataTransfer() async {
return await _channel.invokeMethod('getWifiOnlyDataTransfer');
}
/// Updates the wifiOnlyDataTransfer value.
Future<void> setWifiOnlyDataTransfer(bool wifiOnlyDataTransfer) async {
await _channel.invokeMethod('setWifiOnlyDataTransfer',
{'wifiOnlyDataTransfer': wifiOnlyDataTransfer});
}
/// Starts tracking.
Future<void> start() async {
final isTrackingActiveBefore = await isTrackingActive();
await _channel.invokeMethod('start');
// Simulate a [StartedEvent] event on Android to match the iOS behavior
if (_isAndroid && !isTrackingActiveBefore) {
_observer?.call(StartedEvent());
}
}
/// Stops tracking.
Future<void> stop() async {
final isTrackingActiveBefore = await isTrackingActive();
await _channel.invokeMethod('stop');
// Simulate a [StoppedEvent] event on Android to match the iOS behavior
if (_isAndroid && isTrackingActiveBefore) {
_observer?.call(StoppedEvent());
}
}
/// Deletes all stored user data from the SDK.
Future<void> clearData() async {
await _channel.invokeMethod('clearData');
}
/// Returns `true` if the tracking is active and collecting data, `false` otherwise.
Future<bool> isTrackingActive() async {
return await _channel.invokeMethod('isTrackingActive');
}
/// Returns `true` if the Power save mode is enabled,
/// `false` otherwise.
Future<bool> isPowerSaveModeEnabled() async {
return await _channel.invokeMethod('isPowerSaveModeEnabled');
}
/// Returns `true` if the Battery Optimizations is enabled,
/// `false` otherwise.
Future<bool> isBatteryOptimizationsEnabled() async {
return await _channel.invokeMethod('isBatteryOptimizationsEnabled');
}
Future<dynamic> _methodCallHandler(MethodCall call) async {
switch (call.method) {
case 'onEvent':
_processOnEvent(call.arguments);
break;
}
}
void _processOnEvent(dynamic arguments) {
var eventType = MotionTagEventType.getById(arguments['type']);
if (eventType == null) return;
switch (eventType) {
case MotionTagEventType.started:
_processStartedEvent(arguments);
break;
case MotionTagEventType.stopped:
_processStoppedEvent(arguments);
break;
case MotionTagEventType.location:
_processLocationEvent(arguments);
break;
case MotionTagEventType.transmissionSuccess:
_processTransmissionSuccessEvent(arguments);
break;
case MotionTagEventType.transmissionError:
_processTransmissionErrorEvent(arguments);
break;
}
}
void _processStartedEvent(dynamic arguments) {
var event = StartedEvent();
_observer?.call(event);
}
void _processStoppedEvent(dynamic arguments) {
var event = StoppedEvent();
_observer?.call(event);
}
void _processLocationEvent(dynamic arguments) {
var timestamp = arguments['timestamp'];
var event = LocationEvent(
timestamp: DateTime.fromMillisecondsSinceEpoch(timestamp),
latitude: arguments['latitude'],
longitude: arguments['longitude'],
horizontalAccuracy: arguments['horizontalAccuracy'],
speed: arguments['speed'],
altitude: arguments['altitude'],
bearing: arguments['bearing']);
_observer?.call(event);
}
void _processTransmissionSuccessEvent(dynamic arguments) {
var trackedFrom = arguments['trackedFrom'];
var trackedTo = arguments['trackedTo'];
var event = TransmissionSuccessEvent(
trackedFrom: DateTime.fromMillisecondsSinceEpoch(trackedFrom),
trackedTo: DateTime.fromMillisecondsSinceEpoch(trackedTo));
_observer?.call(event);
}
void _processTransmissionErrorEvent(dynamic arguments) {
var event = TransmissionErrorEvent(arguments['error']);
_observer?.call(event);
}
}