Fetching device information is essential for diagnostics, logging, analytics, support tools, and conditional app behavior. Modern Android provides structured APIs to safely retrieve details like device model, OS version, hardware identifiers, locale, screen metrics, and more — while respecting privacy restrictions.
This updated guide on javatechig.com explains how to access key device information using current Android APIs with Kotlin and Java examples.
Why Collect Device Information?
You might need device info for:
- Crash reports and diagnostics
- Analytics and usage segmentation
- Adapting UI for screen size/resolution
- Feature gating based on OS or device capability
Always respect privacy and avoid collecting personally identifiable information without proper consent.
Basic Device Properties
Device Model & Manufacturer
These identify the device make and brand:
Kotlin
val manufacturer = Build.MANUFACTURER
val model = Build.MODEL
Java
String manufacturer = Build.MANUFACTURER;
String model = Build.MODEL;
Combine them to form a friendly name:
val deviceName = "$manufacturer $model"
OS Version & API Level
val osVersion = Build.VERSION.RELEASE
val apiLevel = Build.VERSION.SDK_INT
This helps you identify the running Android release (e.g., “Android 14”) and program compatibility.
Hardware & Build Info
You can retrieve additional device build properties:
| Property | API |
|---|---|
| Device name | Build.DEVICE |
| Board | Build.BOARD |
| Hardware | Build.HARDWARE |
| Product | Build.PRODUCT |
Example:
val hardware = Build.HARDWARE
Screen Display Metrics
Understanding screen size and density is essential for responsive design.
Kotlin
val metrics = Resources.getSystem().displayMetrics
val width = metrics.widthPixels
val height = metrics.heightPixels
val density = metrics.density
Java
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
float density = metrics.density;
Use these values for layout calculations or conditional logic for different form factors.
Locale and Time Zone
Locale settings help customize region‑specific behavior:
val locale = Locale.getDefault().toString()
val timeZone = TimeZone.getDefault().id
This is useful for formatting dates, numbers, and language‑specific features.
Battery & Charging State
You can monitor battery level with BatteryManager:
Kotlin
val bm = getSystemService(BATTERY_SERVICE) as BatteryManager
val batteryLevel = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
Knowing the battery helps tailor performance or sync jobs.
Unique Device Identifiers (Scoped)
Due to privacy policies (Android 10+), hardware identifiers are restricted. Use scoped identifiers instead:
Android ID
val androidId = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
This ID is unique per app installation and reset on factory reset.
Note: Avoid using IMEI, MAC, or serial number for analytics — they are restricted.
Build Tags & Fingerprint
For more detailed build identification:
val buildTags = Build.TAGS
val fingerprint = Build.FINGERPRINT
Fingerprint is useful for crash analytics to differentiate builds.
ABI (CPU Architecture)
val supportedABIs = Build.SUPPORTED_ABIS.joinToString(", ")
This lets you know what instruction sets the device supports (e.g., “arm64‑v8a”).
Runtime Capabilities (Feature Checks)
Use PackageManager to check support for features:
val hasCamera = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
Check for multi‑touch, NFC, sensors, etc., before performing hardware‑specific actions.
Permissions & Privacy
Many identifiers are restricted for privacy. Android disallows:
- IMEI access without special privileges
- MAC address access since Android 6+
- Serial number access since Android 10+
Always:
- Request appropriate permissions
- Declare them in AndroidManifest.xml
- Respect runtime permission prompts
Best Practices (2026 Updated)
- Avoid collecting sensitive identifiers
- Use android_id for app‑scoped ID needs
- Use feature checks instead of exception‑based logic
- Respect user locale and battery state
- Profile device-specific behaviors with metrics
Example: Collecting Device Info in JSON
val deviceInfo = JSONObject().apply {
put("model", Build.MODEL)
put("osVersion", Build.VERSION.RELEASE)
put("api", Build.VERSION.SDK_INT)
put("screen", "$width x $height")
put("locale", Locale.getDefault())
}
This is useful for sending diagnostics or environment info to analytics.
Troubleshooting
Missing Values
Cause: Restricted APIs
Fix: Use scoped identifiers (android_id) and safe fallbacks.
Null or Unavailable Metrics
Cause: Running outside Activity context
Fix: Use proper context (applicationContext) when retrieving metrics.


