device_id_manager 1.0.0
device_id_manager: ^1.0.0 copied to clipboard
Cross-platform persistent device ID manager for Flutter. iOS uses Keychain, Android uses MediaDrm + SHA-256 hash. Survives app reinstalls.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:device_id_manager/device_id_manager.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Device ID Manager Example',
theme: ThemeData(
colorSchemeSeed: Colors.blue,
useMaterial3: true,
),
home: const DeviceIdScreen(),
);
}
}
class DeviceIdScreen extends StatefulWidget {
const DeviceIdScreen({super.key});
@override
State<DeviceIdScreen> createState() => _DeviceIdScreenState();
}
class _DeviceIdScreenState extends State<DeviceIdScreen> {
String _deviceId = 'Initializing...';
String _status = 'Anonymous';
String? _appUserId;
bool _initialized = false;
final _userIdController = TextEditingController();
@override
void initState() {
super.initState();
_initDeviceId();
}
@override
void dispose() {
_userIdController.dispose();
super.dispose();
}
Future<void> _initDeviceId() async {
await DeviceIdManager.initialize();
setState(() {
_deviceId = DeviceIdManager.deviceId;
_appUserId = DeviceIdManager.appUserId;
_status = DeviceIdManager.isAnonymous ? 'Anonymous' : 'Identified';
_initialized = true;
});
}
Future<void> _logIn() async {
final userId = _userIdController.text.trim();
if (userId.isEmpty) return;
await DeviceIdManager.logIn(userId);
setState(() {
_appUserId = DeviceIdManager.appUserId;
_status = 'Identified';
});
_userIdController.clear();
}
Future<void> _logOut() async {
await DeviceIdManager.logOut();
setState(() {
_deviceId = DeviceIdManager.deviceId;
_appUserId = null;
_status = 'Anonymous';
});
}
Future<void> _clearAll() async {
await DeviceIdManager.clearUserId();
setState(() {
_deviceId = 'Cleared';
_appUserId = null;
_status = 'Anonymous';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Device ID Manager')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_infoCard('Device ID', _deviceId),
const SizedBox(height: 12),
_infoCard('Status', _status),
const SizedBox(height: 12),
_infoCard('App User ID', _appUserId ?? 'None'),
const SizedBox(height: 12),
_infoCard('Custom User ID', _initialized ? DeviceIdManager.customUserId : 'N/A'),
const SizedBox(height: 24),
TextField(
controller: _userIdController,
decoration: const InputDecoration(
labelText: 'App User ID',
hintText: 'Enter a user ID to log in',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: FilledButton(
onPressed: _initialized ? _logIn : null,
child: const Text('Log In'),
),
),
const SizedBox(width: 12),
Expanded(
child: OutlinedButton(
onPressed: _initialized ? _logOut : null,
child: const Text('Log Out'),
),
),
],
),
const SizedBox(height: 12),
SizedBox(
width: double.infinity,
child: TextButton(
onPressed: _initialized ? _clearAll : null,
child: const Text('Clear All IDs'),
),
),
const SizedBox(height: 12),
SizedBox(
width: double.infinity,
child: FilledButton.tonal(
onPressed: _initialized ? _initDeviceId : null,
child: const Text('Re-initialize'),
),
),
],
),
),
);
}
Widget _infoCard(String label, String value) {
return Card(
child: ListTile(
title: Text(label, style: const TextStyle(fontSize: 12, color: Colors.grey)),
subtitle: SelectableText(
value,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
),
),
);
}
}