ponshu-room-lite/lib/services/device_service.dart

73 lines
2.9 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:uuid/uuid.dart';
/// デバイスID取得サービス
/// レート制限・ライセンス管理のためのデバイス識別に使用
///
/// ## 安定性の保証
/// - Android: ANDROID_ID をハッシュ化して使用Factory Reset まで不変)
/// - iOS: SharedPreferences に UUID を永続化identifierForVendor は
/// 全ベンダーアプリ削除後の再インストールで変わるため不使用)
/// - その他/エラー時: SharedPreferences に UUID を永続化
class DeviceService {
static final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin();
static String? _cachedDeviceId;
static const _prefKey = 'ponshu_device_id';
/// デバイス固有のIDを取得SHA256ハッシュ化
static Future<String> getDeviceId() async {
if (_cachedDeviceId != null) return _cachedDeviceId!;
final prefs = await SharedPreferences.getInstance();
// SharedPreferencesに永続化済みならそれを使う再インストール後も同じIDを返す
final stored = prefs.getString(_prefKey);
if (stored != null && stored.isNotEmpty) {
_cachedDeviceId = stored;
debugPrint('[Device] Using persisted device ID: ${stored.substring(0, 8)}...');
return _cachedDeviceId!;
}
// 初回: ハードウェアIDから生成してSharedPreferencesに保存
final id = await _generateAndPersist(prefs);
_cachedDeviceId = id;
return id;
}
static Future<String> _generateAndPersist(SharedPreferences prefs) async {
String deviceIdentifier;
try {
if (defaultTargetPlatform == TargetPlatform.android) {
final info = await _deviceInfo.androidInfo;
// ANDROID_ID: アプリ再インストールでは変わらない。Factory Resetで変わる。
deviceIdentifier = 'android-${info.id}';
} else {
// iOS / その他: UUIDを生成して永続化
// identifierForVendor は全ベンダーアプリ削除後の再インストールで変わるため不使用
deviceIdentifier = 'uuid-${const Uuid().v4()}';
}
} catch (e) {
debugPrint('[Device] Failed to get hardware ID, using UUID fallback: $e');
deviceIdentifier = 'fallback-${const Uuid().v4()}';
}
final id = sha256.convert(utf8.encode(deviceIdentifier)).toString();
await prefs.setString(_prefKey, id);
debugPrint('[Device] Generated and persisted device ID: ${id.substring(0, 8)}...');
return id;
}
/// デバイス情報をリセット(テスト用)
static Future<void> reset() async {
_cachedDeviceId = null;
final prefs = await SharedPreferences.getInstance();
await prefs.remove(_prefKey);
}
}