196 lines
7.3 KiB
Dart
196 lines
7.3 KiB
Dart
// Eszközazonosítás és eszközinformációk.
|
|
//
|
|
// Tárolás:
|
|
// FlutterSecureStorage → appInstanceId (UUID), deviceLabel
|
|
// MethodChannel → ANDROID_ID, rendszer eszköznév
|
|
// device_info_plus → gyártó, modell, OS verzió
|
|
// package_info_plus → app verzió
|
|
|
|
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:device_info_plus/device_info_plus.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
import 'package:uuid/uuid.dart';
|
|
|
|
import '../models/device_info_model.dart';
|
|
|
|
class DeviceIdentityService extends GetxService {
|
|
static DeviceIdentityService get to => Get.find();
|
|
|
|
// ── Konstansok ────────────────────────────────────────────────────
|
|
|
|
static const _channel = MethodChannel('hu.app_dev.terepi_seged/deviceInfo');
|
|
|
|
static const _storage = FlutterSecureStorage(
|
|
aOptions: AndroidOptions(
|
|
encryptedSharedPreferences: true, // Android Keystore alapú titkosítás
|
|
),
|
|
iOptions: IOSOptions(
|
|
accessibility: KeychainAccessibility.first_unlock_this_device,
|
|
),
|
|
);
|
|
|
|
static const _keyInstanceId = 'device_app_instance_id';
|
|
static const _keyLabel = 'device_label';
|
|
|
|
// ── Publikus mezők ────────────────────────────────────────────────
|
|
|
|
/// Statikus eszközinformációk — egyszer töltődik be, nem változik.
|
|
late final DeviceInfoModel info;
|
|
|
|
/// Felhasználó által megadott eszköznév — reaktív, szerkeszthető.
|
|
/// Alapértelmezett: rendszer eszköznév (pl. "Pista telefonja").
|
|
final deviceLabel = ''.obs;
|
|
|
|
bool _isReady = false;
|
|
bool get isReady => _isReady;
|
|
|
|
// ── Lifecycle ─────────────────────────────────────────────────────
|
|
|
|
@override
|
|
Future<void> onReady() async {
|
|
super.onReady();
|
|
await _load();
|
|
// Háttérben regisztrálás — nem blokkolja az UI-t
|
|
unawaited(_registerDevice());
|
|
_isReady = true;
|
|
}
|
|
|
|
// ── Betöltés ──────────────────────────────────────────────────────
|
|
|
|
Future<void> _load() async {
|
|
// Párhuzamos lekérdezések az indulás gyorsításához
|
|
final results = await Future.wait([
|
|
_getOrCreateInstanceId(),
|
|
_getSystemDeviceName(),
|
|
_getStoredLabel(),
|
|
DeviceInfoPlugin().androidInfo,
|
|
PackageInfo.fromPlatform(),
|
|
]);
|
|
|
|
final instanceId = results[0] as String;
|
|
final systemName = results[1] as String;
|
|
final storedLabel = results[2] as String?;
|
|
final android = results[3] as AndroidDeviceInfo;
|
|
final pkg = results[4] as PackageInfo;
|
|
|
|
// ANDROID_ID — MethodChannel-en keresztül (Settings.Secure.ANDROID_ID)
|
|
final androidId = await _getAndroidId() ?? android.fingerprint;
|
|
print('AndroidId: $androidId');
|
|
|
|
info = DeviceInfoModel(
|
|
deviceId: androidId,
|
|
appInstanceId: instanceId,
|
|
manufacturer: android.manufacturer,
|
|
model: android.model,
|
|
brand: android.brand,
|
|
systemDeviceName: systemName,
|
|
osVersion: android.version.release,
|
|
sdkInt: android.version.sdkInt,
|
|
securityPatch: android.version.securityPatch ?? '',
|
|
appVersion: pkg.version,
|
|
buildNumber: pkg.buildNumber,
|
|
);
|
|
|
|
// Label: tárolt érték > rendszer neve
|
|
deviceLabel.value = storedLabel ?? systemName;
|
|
print('Device label: ${deviceLabel.value}');
|
|
}
|
|
|
|
// ── SecureStorage műveletek ───────────────────────────────────────
|
|
|
|
Future<String> _getOrCreateInstanceId() async {
|
|
final existing = await _storage.read(key: _keyInstanceId);
|
|
if (existing != null) return existing;
|
|
|
|
final newId = const Uuid().v4();
|
|
await _storage.write(key: _keyInstanceId, value: newId);
|
|
return newId;
|
|
}
|
|
|
|
Future<String?> _getStoredLabel() => _storage.read(key: _keyLabel);
|
|
|
|
// ── MethodChannel hívások ─────────────────────────────────────────
|
|
|
|
/// Settings.Secure.ANDROID_ID — egyedi, app-specifikus (Android 8+)
|
|
Future<String?> _getAndroidId() async {
|
|
try {
|
|
return await _channel.invokeMethod<String>('getAndroidId');
|
|
} catch (_) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// Settings.Global.DEVICE_NAME — felhasználó által adott eszköznév
|
|
Future<String> _getSystemDeviceName() async {
|
|
try {
|
|
final name = await _channel.invokeMethod<String>('getAndroidDeviceName');
|
|
if (name != null && name.isNotEmpty) return name;
|
|
} catch (_) {}
|
|
// Fallback: gyártó + modell
|
|
if (Platform.isAndroid) {
|
|
final a = await DeviceInfoPlugin().androidInfo;
|
|
return '${a.manufacturer} ${a.model}';
|
|
}
|
|
return 'Eszköz';
|
|
}
|
|
|
|
// ── Eszköznév beállítása ──────────────────────────────────────────
|
|
|
|
/// Felhasználó által megadott eszköznév mentése.
|
|
/// Üres string esetén visszaáll a rendszer névhez.
|
|
Future<void> setLabel(String label) async {
|
|
final trimmed = label.trim();
|
|
|
|
if (trimmed.isEmpty) {
|
|
// Visszaállás rendszer névre
|
|
await _storage.delete(key: _keyLabel);
|
|
deviceLabel.value = info.systemDeviceName;
|
|
} else {
|
|
await _storage.write(key: _keyLabel, value: trimmed);
|
|
deviceLabel.value = trimmed;
|
|
}
|
|
|
|
unawaited(_registerDevice());
|
|
}
|
|
|
|
// ── Supabase regisztráció ─────────────────────────────────────────
|
|
|
|
Future<void> _registerDevice() async {
|
|
// await Supabase.instance.client
|
|
// .from('devices')
|
|
// .upsert(
|
|
// info.toRegistrationMap(label: deviceLabel.value),
|
|
// onConflict: 'device_id',
|
|
// );
|
|
}
|
|
|
|
// ── Gyors elérők (kényelemért) ────────────────────────────────────
|
|
|
|
String get deviceId => _isReady ? info.deviceId : '';
|
|
String get appInstanceId =>
|
|
_isReady ? info.appInstanceId : ''; // ← _isReady guard hiányzott
|
|
String get deviceLabelSync => deviceLabel.value; // ← ÚJ
|
|
String get model => _isReady ? '${info.manufacturer} ${info.model}' : '';
|
|
String get osInfo =>
|
|
_isReady ? 'Android ${info.osVersion} (SDK ${info.sdkInt})' : '';
|
|
String get appInfo =>
|
|
_isReady ? '${info.appVersion}+${info.buildNumber}' : '';
|
|
// ── Debug ─────────────────────────────────────────────────────────
|
|
|
|
@override
|
|
String toString() => [
|
|
'DeviceIdentityService',
|
|
' deviceId: ${info.deviceId}',
|
|
' instanceId: ${info.appInstanceId}',
|
|
' label: ${deviceLabel.value}',
|
|
' model: $model',
|
|
' os: $osInfo',
|
|
' app: $appInfo',
|
|
].join('\n');
|
|
}
|