да, вам нужно проверить подлинность и использовать некоторые переменные, например:
String _cookie;
String _email = "your_email";
String _password = "your_password" ;
final _dio = Dio();
String _cookie;
String serverUrl = "your_server_ip";
StreamSubscription<dynamic> _rawPosSub;
final _devicesMap = <int, Device>{};
final _positions = StreamController<Device>.broadcast();
Future<void> _getConnection({String protocol = "http", String email, String password}) async {
final addr = "$protocol://$serverUrl/api/session";
Map<String, String> body = {
'email' : '$email',
'password': '$password',
};
final response = await Dio().post(addr, data: body,
options: new Options(contentType:"application/x-www-form-urlencoded"));
_cookie = response.headers["set-cookie"][0];
print(_cookie);
}
Далее вам необходимо создать класс устройств (не забудьте изменить имя проекта в строке импорта utils)
import 'package:geopoint/geopoint.dart';
import 'package:your_project/utils/utils.dart';
/// A class representing a device
class Device {
/// Main constructor
Device(
{this.id,
this.uniqueId,
this.groupId,
this.name,
this.position,
this.batteryLevel,
this.keepAlive = 1,
this.isActive,
this.isDisabled,
this.properties = const <String, dynamic>{}});
/// The device database id
final int id;
/// The on device unique id
String uniqueId;
/// The group of the device
int groupId;
/// The device name
String name;
/// The device position
DevicePosition position;
/// The device battery level
double batteryLevel;
/// Minutes a device is considered alive
int keepAlive;
/// The device can be disabled
bool isDisabled;
/// false if the device has never updated one position
bool isActive;
/// Extra properties for the device
Map<String, dynamic> properties;
/// Is the device online
bool get isAlive => _isDeviceAlive();
/// Create a device from json data
Device.fromPosition(Map<String, dynamic> data,
{String timeZoneOffset = "0", int keepAlive = 1})
: this.keepAlive = keepAlive,
this.id = int.parse(data["deviceId"].toString()),
this.position =
DevicePosition.fromJson(data, timeZoneOffset: timeZoneOffset),
this.batteryLevel =
double.parse(data["attributes"]["batteryLevel"].toString());
bool _isDeviceAlive() {
if (position == null) {
return false;
}
final now = DateTime.now();
final dateAlive = now.subtract(Duration(minutes: keepAlive));
bool isAlive = false;
if (position.date.isAfter(dateAlive)) {
isAlive = true;
}
return isAlive;
}
/// Print a description of the device
void describe() {
print("Device:");
print(" - id : $id");
print(" - uniqueId : $uniqueId");
print(" - name : $name");
print(" - batteryLevel: $batteryLevel");
print(" - position : $position");
}
@override
String toString() {
String _name = "$uniqueId";
if (name != null) {
_name = name;
}
String res;
if (position != null) {
res = "$_name: $position";
} else {
res = "$_name";
}
return res;
}
}
/// A class to handle a device position
class DevicePosition {
/// The position database id
final int id;
/// The geo data
final GeoPoint geoPoint;
/// The distance since previous point
final double distance;
/// The total distance for the device
final double totalDistance;
/// The address of the device position
final String address;
/// The date of the position
DateTime date;
/// Create a position from json
DevicePosition.fromJson(Map<String, dynamic> data,
{String timeZoneOffset = "0"})
: this.id = int.parse(data["id"].toString()),
this.geoPoint = GeoPoint(
name: data["id"].toString(),
latitude: double.parse(data["latitude"].toString()),
longitude: double.parse(data["longitude"].toString()),
speed: double.parse(data["speed"].toString()),
accuracy: double.parse(data["accuracy"].toString()),
altitude: double.parse(data["altitude"].toString())),
this.distance = double.parse(data["attributes"]["distance"].toString()),
this.totalDistance =
double.parse(data["attributes"]["totalDistance"].toString()),
this.address = data["address"].toString() {
this.date = dateFromUtcOffset(data["fixTime"].toString(), timeZoneOffset);
}
@override
String toString() {
return "$date : ${geoPoint.latitude}, ${geoPoint.longitude}";
}
}
Также вам следует использовать метод utils
/// parse a date
DateTime dateFromUtcOffset(String dateStr, String timeZoneOffset) {
DateTime d = DateTime.parse(dateStr);
if (timeZoneOffset.startsWith("+")) {
final of = int.parse(timeZoneOffset.replaceFirst("+", ""));
d = d.add(Duration(hours: of));
} else if (timeZoneOffset.startsWith("-")) {
final of = int.parse(timeZoneOffset.replaceFirst("-", ""));
d = d.subtract(Duration(hours: of));
}
return d;
}
Наконец, для прослушивания позиций вам понадобятся следующие методы:
/// Get the device positions
Future<Stream<Device>> positions() async {
final posStream =
await _positionsStream(serverUrl: serverUrl, email: _email, password: _password);
_rawPosSub = posStream.listen((dynamic data) {
print("DATA $data");
final dataMap = json.jsonDecode(data.toString()) as Map<String, dynamic>;
if (dataMap.containsKey("positions")) {
DevicePosition pos;
for (final posMap in dataMap["positions"]) {
//print("POS MAP $posMap");
pos = DevicePosition.fromJson(posMap as Map<String, dynamic>);
final id = posMap["deviceId"] as int;
Device device;
if (_devicesMap.containsKey(id)) {
device = _devicesMap[id];
} else {
device = Device.fromPosition(posMap as Map<String, dynamic>,
keepAlive: 1);
}
device.position = pos;
_devicesMap[id] = device;
_positions.sink.add(device);
}
} else {
for (final d in dataMap["devices"]) {
if (!_devicesMap.containsKey(d["id"])) {
final id = int.parse(d["id"].toString());
d["name"] ??= d["id"].toString();
final device = Device(id: id, name: d["name"].toString());
_devicesMap[id] = device;
//print(" - ${device.name}");
}
}
}
});
return _positions.stream;
}
Future<Stream<dynamic>> _positionsStream(
{String serverUrl, String email, String password, String protocol = "http"}) async {
if (_cookie == null) {
await _getConnection(email: _email, password: _password);
}
final channel = IOWebSocketChannel.connect("ws://$serverUrl/api/socket",
headers: <String, dynamic>{"Cookie": _cookie});
return channel.stream;
}
Когда вы закончите sh, вы можете позвонить
_init() async {
_getConnection(email: _email, password: _password);
final pos = await positions();
print("Listening for position updates");
pos.listen((device) {
print("POSITION UPDATE: $device");
print("${device.id}: ${device.position.geoPoint.latitude} / " +
"${device.position.geoPoint.longitude}");
});
}
Также я использую эти зависимости и стабильную версию 1.17.0 флаттера:
dio: ^3.0.9
web_socket_channel:
geopoint: ^0.7.1
Примечание: Я использую код из traccar_client 0.1.0 и измените его для доступа по электронной почте и паролю, но если вам нужно использовать токен, вы можете следовать примеру с https://github.com/synw/traccar_client. Кредиты им. :)