Device Identifier Plugin
A comprehensive Flutter plugin for obtaining various device identifiers, supporting both Android and iOS platforms.
Features
Android Supported Identifiers
- Android ID: Unique device identifier (recommended)
- DRM ID: Digital Rights Management Identifier (Widevine id)
- Advertising ID: Google Advertising Identifier (GAID)
- Install UUID: Unique ID generated on app installation
- Device Fingerprint: Identifier generated based on hardware info
- Build Serial: Device serial number (requires permission)
- File-based ID: Persistent ID stored in external storage
- Combined ID: Hash of multiple identifiers
iOS Supported Identifiers
- iOS Device ID: Concept similar to Android ID (recommended)
- IDFV: Identifier for Vendor, shared among the same developer's apps
- IDFA: Advertising Identifier (requires user authorization)
- Keychain UUID: Stable identifier stored in the keychain
- Device Fingerprint: Identifier generated based on hardware info
- Launch UUID: Temporary ID generated on each app launch
- Combined ID: Hash of multiple identifiers
Installation
Add to your pubspec.yaml
:
dependencies:
device_identifier_plugin: ^1.0.1
Then run:
flutter pub get
Platform Setup
Android
Configure AndroidManifest.xml
Add the following permissions to your android/app/src/main/AndroidManifest.xml
as needed:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Note, don't forget the line xmlns:tools='xxxxx' above -->
<!-- Basic permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- For serial number (optional) -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- If you need to obtain a Google Advertising ID (optional) -->
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
<!-- For file-based ID (optional) -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 11+ File access, if file storage device identifier is required (optional) -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<application>
...
</application>
</manifest>
Configure app/build.gradle, minimum supported SDK 21
android {
defaultConfig {
minSdkVersion 21
}
}
Tip: If you need to obtain GAID, your device must support Google services
iOS
Add the following to your ios/Runner/Info.plist
for advertising tracking:
Privacy - Tracking Usage Description
<key>NSUserTrackingUsageDescription</key>
<string>This app would like to access IDFA for analytics and personalized ads.</string>
Please check whether there is an AppTrackingTransparency.framework in this path:
Xcode - Build Phases - Link Binary With Libraries add AppTrackingTransparency.framework
The minimum supported version for iOS is 14. Please modify it in Podfile
platform :ios, '14.0'
Usage
Import the package:
import 'package:device_identifier_plugin/device_identifier_plugin.dart';
Singleton Access
final deviceIdentifier = DeviceIdentifierPlugin.instance;
Get the Best Device Identifier
String bestId = await deviceIdentifier.getBestDeviceIdentifier();
print('Best Device ID: $bestId');
Check if Device is an Emulator
bool isEmulator = await deviceIdentifier.isEmulator();
print('Is Emulator: $isEmulator');
Get Device Info
Map<String, String?> deviceInfo = await deviceIdentifier.getDeviceInfo();
print('Device Info: $deviceInfo');
Get Supported Identifiers
Map<String, dynamic> identifiers = await deviceIdentifier.getSupportedIdentifiers();
print('Supported Identifiers: $identifiers');
Get Platform Version
String? platformVersion = await deviceIdentifier.getPlatformVersion();
print('Platform Version: $platformVersion');
Android-specific: File-based Device Identifier
// Request storage permission first
await deviceIdentifier.requestExternalStoragePermission();
bool hasPermission = await deviceIdentifier.hasExternalStoragePermission();
if (hasPermission) {
// Get file-based device identifier
String? fileId = await deviceIdentifier.getFileDeviceIdentifier();
print('File Device ID: $fileId');
// Generate a new file-based device identifier if needed
String? generatedId = await deviceIdentifier.generateFileDeviceIdentifier();
print('Generated File Device ID: $generatedId');
// Check if file-based device identifier exists
bool exists = await deviceIdentifier.hasFileDeviceIdentifier();
print('File Device ID Exists: $exists');
// Delete file-based device identifier
bool deleted = await deviceIdentifier.deleteFileDeviceIdentifier();
print('File Device ID Deleted: $deleted');
}
Android-specific: Get the Android ID, Advertising Identifier, and Widevine Id
if (Platform.isAndroid) {
String? androidId = await deviceIdentifier.getAndroidId();
print('Android ID: $androidId');
String? advertisingId = await deviceIdentifier.getAdvertisingIdForAndroid();
print('Advertising ID: $advertisingId');
/// DRM ID
String? drmId = await deviceIdentifier.getWidevineDrmId();
print('DRM ID: $drmId');
}
iOS-specific: Advertising ID and Tracking Authorization
if (Platform.isIOS) {
// Request tracking authorization (iOS 14.5+)
String? status = await deviceIdentifier.requestTrackingAuthorization();
print('Tracking Authorization Status: $status');
// Get IDFA (after authorization)
String? idfa = await deviceIdentifier.getAdvertisingIdForiOS();
print('IDFA: $idfa');
}
iOS-specific: Keychain UUID
if (Platform.isIOS) {
bool exists = await deviceIdentifier.hasKeychainUUID();
String? uuid = await deviceIdentifier.getKeychainUUID();
if (!exists) {
uuid = await deviceIdentifier.generateKeychainUUID();
}
print('Keychain UUID: $uuid');
}
iOS-specific: Get Apple IDFV
if (Platform.isIOS) {
String? idfv = await deviceIdentifier.getAppleIDFV();
print('Apple IDFV: $idfv');
}
iOS-specific: Set Keychain Service and Account
if (Platform.isIOS) {
await deviceIdentifier.setKeychainServiceAndAccount(
service: 'com.example.myapp.keychain',
keyAccount: 'my_device_uuid',
deviceIDAccount: 'my_ios_device_id',
);
print('Custom keychain service and account set.');
}
API Reference
Method | Return Type | Description | Platform |
---|---|---|---|
getPlatformVersion() |
Future<String?> |
Get platform version | Android, iOS |
getBestDeviceIdentifier() |
Future<String> |
Get the best device identifier for the current platform | Android, iOS |
isEmulator() |
Future<bool> |
Check if the device is an emulator | Android, iOS |
getDeviceInfo() |
Future<Map<String, String?>> |
Get detailed device info | Android, iOS |
getSupportedIdentifiers() |
Future<Map<String, dynamic>> |
Get all supported identifiers | Android, iOS |
getAdvertisingIdForiOS() |
Future<String?> |
Get IDFA (requires user authorization) | iOS |
requestTrackingAuthorization() |
Future<String?> |
Request tracking authorization (iOS 14.5+) | iOS |
getAppleIDFV() |
Future<String?> |
Get IDFV (Identifier for Vendor) | iOS |
getKeychainUUID() |
Future<String?> |
Get Keychain UUID | iOS |
hasKeychainUUID() |
Future<bool> |
Check if Keychain UUID exists | iOS |
generateKeychainUUID() |
Future<String?> |
Generate and store a new Keychain UUID | iOS |
setKeychainServiceAndAccount({String service, String keyAccount, String deviceIDAccount}) |
Future<void> |
Set custom keychain service and account | iOS |
getWidevineDrmId() |
Future<String?> |
Get Android DRM ID) | Android |
getAdvertisingIdForAndroid() |
Future<String?> |
Get Google Advertising ID (GAID) | Android |
getAndroidId() |
Future<String?> |
Get Android ID | Android |
getFileDeviceIdentifier({String? fileName, String? folderName}) |
Future<String?> |
Get file-based device identifier | Android |
generateFileDeviceIdentifier({String? fileName, String? folderName}) |
Future<String?> |
Generate and store a new file-based device identifier | Android |
deleteFileDeviceIdentifier({String? fileName, String? folderName}) |
Future<bool> |
Delete file-based device identifier | Android |
hasFileDeviceIdentifier({String? fileName, String? folderName}) |
Future<bool> |
Check if file-based device identifier exists | Android |
requestExternalStoragePermission() |
Future<void> |
Request external storage permission | Android |
hasExternalStoragePermission() |
Future<bool> |
Check if external storage permission is granted | Android |
Privacy & Compliance
- iOS: Fully supports App Tracking Transparency (ATT) and requires user authorization for IDFA.
- Android: Handles runtime permissions for storage and complies with Google Play policies for advertising ID.
- General: Only collect device identifiers when necessary and inform users about the purpose.
License
MIT License. See LICENSE for details.
Changelog
See CHANGELOG.md for version history.
Contribution
Contributions are welcome! Please submit issues or pull requests via GitHub.