import 'dart:io'; import 'package:adjust_sdk/adjust.dart'; import 'package:flutter/foundation.dart'; import 'package:uuid/uuid.dart'; import 'package:android_id/android_id.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter_vpn_detector/vpn_checker.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:play_install_referrer/play_install_referrer.dart'; import 'package:shared_preferences/shared_preferences.dart'; class DeviceInfo { static const String _spInstallReferrer = "installReferrer"; static const int defaultTimeout = 1000; static const int defaultMaxTimeout = 2000; DeviceInfo._(); static final DeviceInfo I = DeviceInfo._(); Future> deviceInfo({ int adidTimeout = -1, bool includeInstallReferrer = false, bool includeAdjust = true, }) async { final Map json = {}; try { adidTimeout = getTimeOut(adidTimeout); final packageInfo = await PackageInfo.fromPlatform(); final devicePlugin = DeviceInfoPlugin(); final locale = PlatformDispatcher.instance.locale; bool isActive = await VpnChecker.isVpnActive(); json["isVpn"] = isActive; json["country"] = locale.countryCode; json["language"] = locale.languageCode; json["packageName"] = packageInfo.packageName; json["versionName"] = packageInfo.version; json["versionCode"] = packageInfo.buildNumber; if (Platform.isAndroid) { final androidInfo = await devicePlugin.androidInfo; json["osVersion"] = androidInfo.version.release; json["sdkInt"] = androidInfo.version.sdkInt.toString(); json["brand"] = androidInfo.brand; json["model"] = androidInfo.model; json["device"] = androidInfo.device; json["androidId"] = await getAndroidId(); } else if (Platform.isIOS) { final iosInfo = await devicePlugin.iosInfo; json["osVersion"] = iosInfo.systemVersion; json["model"] = iosInfo.model; json["device"] = iosInfo.modelName; json["androidId"] = iosInfo.identifierForVendor; json['idfv'] = iosInfo.identifierForVendor; try { json['idfa'] = await Adjust.getIdfa(); if (includeAdjust) { json['adjustAdId'] = await Adjust.getAdid(); final adjustAttribution = await Adjust.getAttribution(); json['adjustAttribution'] = adjustAttribution.jsonResponse; json["clickLable"] = adjustAttribution.clickLabel; } } catch (_) {} debugPrint("$iosInfo"); } if (includeInstallReferrer) { final installReferrer = await getInstallReferrer(timeout: adidTimeout); if (installReferrer != null && installReferrer.isNotEmpty) { json["installReferrer"] = installReferrer; } } } catch (e) { debugPrint("[DeviceInfo] load adjust/referrer failed: $e"); } return json; } Future getInstallReferrer({int timeout = 2000}) async { try { final prefs = await SharedPreferences.getInstance(); final cachedReferrer = prefs.getString(_spInstallReferrer); if (cachedReferrer != null && cachedReferrer.isNotEmpty) { return cachedReferrer; } final referrerDetails = await PlayInstallReferrer.installReferrer.timeout( Duration(milliseconds: timeout), ); final referrer = referrerDetails.installReferrer; if (referrer != null && referrer.isNotEmpty) { await prefs.setString(_spInstallReferrer, referrer); } return referrer; } catch (e) { debugPrint("[DeviceInfo] get install referrer failed: $e"); return null; } } int getTimeOut(int timeout) { if (timeout <= 0) { return defaultTimeout; } return timeout; } Future getAndroidId() async { try { AndroidId androidIdPlugin = AndroidId(); final androidId = await androidIdPlugin.getId(); return androidId ?? await createDeviceId(); } catch (e) { debugPrint("[DeviceInfo] get Android ID failed: $e"); return ''; } } Future createDeviceId() async { const key = "createdDeviceId"; SharedPreferences prefs = await SharedPreferences.getInstance(); String? deviceId = prefs.getString(key); if (deviceId != null && deviceId.isNotEmpty) { return deviceId; } final uuid = const Uuid(); deviceId = uuid.v4(); deviceId = deviceId.replaceAll('-', ''); await prefs.setString(key, deviceId); return deviceId; } }