imei_getter 0.3.0
imei_getter: ^0.3.0 copied to clipboard
A Flutter plugin to get device identifiers (IMEI on older Android, ANDROID_ID on newer Android, identifierForVendor on iOS) with proper permission handling.
import 'package:flutter/material.dart';
import 'package:imei_getter/imei_getter.dart';
import 'dart:io' show Platform;
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String? _deviceIdentifier;
bool? _hasPermission;
bool _isLoading = false;
String? _errorMessage;
@override
void initState() {
super.initState();
_checkPermission();
}
Future<void> _checkPermission() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
final hasPermission = await ImeiGetter.hasPermission();
setState(() {
_hasPermission = hasPermission;
_isLoading = false;
});
} catch (e) {
setState(() {
_errorMessage = 'Error checking permission: $e';
_isLoading = false;
});
}
}
Future<void> _requestPermission() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
await ImeiGetter.requestPermission();
// Re-check permission after request
await _checkPermission();
} catch (e) {
setState(() {
_errorMessage = 'Error requesting permission: $e';
_isLoading = false;
});
}
}
DeviceIdentifierType? _identifierType;
Future<void> _getDeviceIdentifier() async {
setState(() {
_isLoading = true;
_errorMessage = null;
_deviceIdentifier = null;
_identifierType = null;
});
try {
final data = await ImeiGetter.getDeviceIdentifierWithInfo();
setState(() {
_deviceIdentifier = data?.id;
_identifierType = data?.type;
_isLoading = false;
});
} catch (e) {
setState(() {
_errorMessage = 'Error getting device identifier: $e';
_isLoading = false;
});
}
}
String _getPlatformInfo() {
if (Platform.isAndroid) {
return 'Android (API ${Platform.version})'; // Simplified
} else if (Platform.isIOS) {
return 'iOS';
}
return 'Unknown';
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'IMEI Getter Example',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('IMEI Getter Example'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Platform Information',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
Text('Platform: ${_getPlatformInfo()}'),
],
),
),
),
const SizedBox(height: 16),
if (Platform.isAndroid)
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Permission Status',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
if (_isLoading)
const CircularProgressIndicator()
else if (_hasPermission != null)
Row(
children: [
Icon(
_hasPermission!
? Icons.check_circle
: Icons.cancel,
color: _hasPermission!
? Colors.green
: Colors.red,
),
const SizedBox(width: 8),
Text(
_hasPermission!
? 'Permission Granted'
: 'Permission Not Granted',
style: TextStyle(
color: _hasPermission!
? Colors.green
: Colors.red,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: _isLoading ? null : _requestPermission,
icon: const Icon(Icons.security),
label: const Text('Request Permission'),
),
const SizedBox(height: 8),
ElevatedButton.icon(
onPressed: _isLoading ? null : _checkPermission,
icon: const Icon(Icons.refresh),
label: const Text('Check Permission'),
),
],
),
),
),
if (Platform.isAndroid) const SizedBox(height: 16),
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Device Identifier',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
if (_isLoading)
const Center(child: CircularProgressIndicator())
else if (_deviceIdentifier != null)
const SizedBox(height: 16),
if (_deviceIdentifier != null) ...[
const Text('Identifier:', style: TextStyle(fontWeight: FontWeight.bold)),
SelectableText(
_deviceIdentifier!,
style: const TextStyle(
fontFamily: 'monospace',
fontSize: 14,
),
),
const SizedBox(height: 8),
const Text('Type:', style: TextStyle(fontWeight: FontWeight.bold)),
Text(_identifierType.toString().split('.').last.toUpperCase()),
] else
const Text(
'No identifier retrieved yet',
style: TextStyle(color: Colors.grey),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: _isLoading ? null : _getDeviceIdentifier,
icon: const Icon(Icons.phone_android),
label: const Text('Get Device Identifier'),
),
],
),
),
),
if (_errorMessage != null) ...[
const SizedBox(height: 16),
Card(
color: Colors.red.shade50,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(Icons.error, color: Colors.red),
const SizedBox(width: 8),
Text(
'Error',
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(color: Colors.red),
),
],
),
const SizedBox(height: 8),
Text(
_errorMessage!,
style: const TextStyle(color: Colors.red),
),
],
),
),
),
],
const SizedBox(height: 16),
Card(
color: Colors.blue.shade50,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(Icons.info, color: Colors.blue),
const SizedBox(width: 8),
Text(
'Privacy Notice',
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(color: Colors.blue),
),
],
),
const SizedBox(height: 8),
const Text(
'• On Android 10+, IMEI access is restricted. The plugin uses ANDROID_ID instead.\n'
'• On iOS, IMEI is not available. The plugin uses identifierForVendor.\n'
'• identifierForVendor resets when all apps from the vendor are uninstalled.\n'
'• Always handle null returns and permission denials gracefully.',
style: TextStyle(fontSize: 12),
),
],
),
),
),
],
),
),
),
);
}
}