import 'dart:convert'; import 'dart:io'; import 'package:crypto/crypto.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; class DeviceInfo { final String fingerprint; final String model; final String osVersion; const DeviceInfo({ required this.fingerprint, required this.model, required this.osVersion, }); } class DeviceFingerprintService { static const _cacheKey = 'device_fingerprint_v1'; static const _storage = FlutterSecureStorage(); static final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin(); static Future getDeviceInfo() async { // 优先读缓存(iOS Keychain 卸载不删除,稳定性更好) final cached = await _storage.read(key: _cacheKey); if (cached != null) { final parts = cached.split('|'); if (parts.length == 3) { return DeviceInfo( fingerprint: parts[0], model: parts[1], osVersion: parts[2], ); } } String rawId; String model; String osVersion; if (Platform.isAndroid) { final info = await _deviceInfo.androidInfo; // ANDROID_ID + manufacturer + model + version rawId = '${info.id}|${info.manufacturer}|${info.model}|${info.version.release}'; model = '${info.manufacturer} ${info.model}'; osVersion = 'Android ${info.version.release}'; } else if (Platform.isIOS) { final info = await _deviceInfo.iosInfo; // identifierForVendor + utsname.machine + systemVersion rawId = '${info.identifierForVendor}|${info.utsname.machine}|${info.systemVersion}'; model = info.model; osVersion = 'iOS ${info.systemVersion}'; } else { rawId = 'unknown'; model = 'unknown'; osVersion = 'unknown'; } final fingerprint = sha256.convert(utf8.encode(rawId)).toString(); // 写入缓存 await _storage.write(key: _cacheKey, value: '$fingerprint|$model|$osVersion'); return DeviceInfo(fingerprint: fingerprint, model: model, osVersion: osVersion); } }