Skip to content

Android 10+ uses ANDROID_ID. Android 8 and 9 uses Build.getSerial() but requires READ_PHONE_STATE.

Notifications You must be signed in to change notification settings

AHMED-HOMISHAN/device_info

Repository files navigation

Cross-Platform Device Info App

This Flutter app retrieves and displays detailed device information across multiple platforms, including Android, iOS, Linux, Windows, macOS, and Web.

Features

  • Device Identifier: Fetches a unique device identifier using platform-specific code through a MethodChannel.
  • Platform-Specific Information: Uses the DeviceInfoPlugin to gather detailed device data, such as OS version, model, manufacturer, memory, and other relevant specs. Each platform has its dedicated method for optimal data handling.
  • Dynamic UI: Automatically adapts the app title and displayed information based on the detected platform. Device details are shown in a scrollable list with clear labeling.
  • Error Handling: Gracefully handles unsupported platforms by displaying an error message if information retrieval fails.

Supported Platforms

  • Android
  • iOS
  • Linux
  • Windows
  • macOS
  • Web
  • Fuchsia (Displays an unsupported message for demonstration purposes)

How It Works

The app initializes by detecting the platform and retrieving device-specific details using the DeviceInfoPlugin. The information is then displayed in a user-friendly format in the UI. This app serves as a useful tool for developers needing device diagnostics or cross-platform device information.

Kotlin class for the MainActivity

Kotlin class for the MainActivity of a Flutter app that interacts with Android's native layer to retrieve a device identifier. It uses a MethodChannel to communicate between Flutter and Android, enabling the app to access platform-specific functionality, such as the device’s serial number or Android ID. Here’s a breakdown of each part:

1. Class Setup and Channel Declaration

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.example.deviceInfo"
    private val REQUEST_PHONE_STATE = 1
  • MainActivity extends FlutterActivity, meaning it's the main entry point for the Android part of a Flutter app.
  • CHANNEL is the unique identifier for the MethodChannel used to communicate with Flutter.
  • REQUEST_PHONE_STATE is a constant representing the request code for permission to read the phone state.

2. Configuring the MethodChannel

override fun configureFlutterEngine(flutterEngine: io.flutter.embedding.engine.FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)

    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
  • configureFlutterEngine is overridden to set up the MethodChannel with Flutter.
  • MethodChannel(...).setMethodCallHandler sets a listener for method calls from Flutter. Here, it listens for the getDeviceIdentifier method to retrieve the device ID.

3. Handling getDeviceIdentifier Method Calls

if (call.method == "getDeviceIdentifier") {
    if (Build.VERSION.SDK_INT in Build.VERSION_CODES.O..Build.VERSION_CODES.P) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
            result.success(getDeviceIdentifier())
        } else {
            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), REQUEST_PHONE_STATE)
            result.success("Permission required")
        }
    } else {
        result.success(getDeviceIdentifier())
    }
} else {
    result.notImplemented()
}
  • If getDeviceIdentifier is called, the code checks the Android version:

    • Android 8-9 (Oreo to Pie): Requires READ_PHONE_STATE permission to access the device's serial number. If permission is granted, it retrieves the device identifier. Otherwise, it requests permission.
    • Other Versions: For Android 10 and later, it uses ANDROID_ID for the device identifier, which does not require permission.
  • If the method called is not getDeviceIdentifier, it responds with notImplemented().

4. Retrieving the Device Identifier

private fun getDeviceIdentifier(): String {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
    } else {
        try {
            Build.getSerial()
        } catch (e: SecurityException) {
            "Permission denied"
        }
    }
}
  • For Android 10 (API level 29) and above, it retrieves ANDROID_ID via Settings.Secure.getString.
  • For versions below Android 10, it attempts to retrieve Build.getSerial(). If the permission is denied, it catches the SecurityException and returns “Permission denied.”

5. Handling Permission Results

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    if (requestCode == REQUEST_PHONE_STATE) {
        if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
            flutterEngine?.dartExecutor?.binaryMessenger?.let { messenger ->
                MethodChannel(messenger, CHANNEL).invokeMethod("getDeviceIdentifier", getDeviceIdentifier())
            }
        }
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
  • onRequestPermissionsResult handles the result of the permission request.
  • If permission is granted, it re-invokes the getDeviceIdentifier method to retrieve and send the identifier back to Flutter.

This setup allows the Flutter app to retrieve a unique device identifier across various Android versions while handling permission requirements and potential exceptions.

About

Android 10+ uses ANDROID_ID. Android 8 and 9 uses Build.getSerial() but requires READ_PHONE_STATE.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published