diff --git a/README.md b/README.md new file mode 100644 index 0000000..7b2a664 --- /dev/null +++ b/README.md @@ -0,0 +1,173 @@ +# Android Device Info Library + +An Android library that provides comprehensive device information including device names, specifications, type detection, and device images. This library helps you get detailed information about Android devices using both local databases and online APIs. + +## Features + +- 📱 **Device Detection**: Automatically detect device type (smartphone, tablet, smartwatch, TV, etc.) +- 🔍 **Device Information**: Get device name, manufacturer, model, codename, and specifications +- 🌐 **Online Database**: Fetch device images and additional info from online APIs +- 💾 **Local Caching**: Cache device information for offline access +- 🚀 **Kotlin Coroutines**: Async operations with proper coroutine support +- 📊 **Device Type Recognition**: Identify emulators, physical devices, and various device categories +- 🔧 **Vendor-Specific Support**: Extensible architecture for vendor-specific features + +## Installation + +Add the library to your Android project: + +### Gradle (Kotlin DSL) +```kotlin +dependencies { + implementation("dev.oxmc:androiddeviceinfo:1.0.0") +} +``` + +### Gradle (Groovy) +```groovy +dependencies { + implementation 'dev.oxmc:androiddeviceinfo:1.0.0' +} +``` + +## Quick Start + +### Basic Device Information + +```kotlin +import dev.oxmc.androiddeviceinfo.AndroidInfo +import dev.oxmc.androiddeviceinfo.DeviceInfo + +// Get basic device info +val brand = AndroidInfo.Info.brand +val model = AndroidInfo.Info.model +val manufacturer = AndroidInfo.Info.manufacturer + +// Get Android version info +val androidVersion = AndroidInfo.Version.release +val sdkVersion = AndroidInfo.Version.sdkInt + +// Get device type +val deviceType = AndroidInfo.getType(context) +println("Device type: $deviceType") // e.g., SMARTPHONE, TABLET, SMARTWATCH +``` + +### Complete Device Information (Async) + +```kotlin +import dev.oxmc.androiddeviceinfo.DeviceInfo +import kotlinx.coroutines.launch + +// In a coroutine scope +lifecycleScope.launch { + val (deviceName, manufacturer, model, codename, imageUrl) = DeviceInfo.getDeviceInfo(context) + + println("Device: $deviceName") + println("Manufacturer: $manufacturer") + println("Model: $model") + println("Codename: $codename") + println("Image URL: $imageUrl") +} +``` + +### Device Type Detection + +```kotlin +import dev.oxmc.androiddeviceinfo.AndroidInfo + +// Check if device is an emulator +if (AndroidInfo.isEmulator) { + println("Running on emulator") +} else { + println("Running on physical device") +} + +// Get specific device type +when (AndroidInfo.getType(context)) { + AndroidInfo.DeviceType.SMARTPHONE -> println("This is a smartphone") + AndroidInfo.DeviceType.TABLET -> println("This is a tablet") + AndroidInfo.DeviceType.SMARTWATCH -> println("This is a smartwatch") + AndroidInfo.DeviceType.SMART_TV -> println("This is a smart TV") + AndroidInfo.DeviceType.EMULATOR -> println("This is an emulator") + // ... other types +} +``` + +## Requirements + +- **Minimum SDK**: API 19 (Android 4.4 KitKat) +- **Target SDK**: API 36+ +- **Kotlin**: 1.8+ +- **Permissions**: No special permissions required + +## Architecture + +The library consists of several main components: + +- **AndroidInfo**: Static device information and type detection +- **DeviceInfo**: Async device information with online lookup +- **DeviceName**: Device name resolution and caching +- **AltDeviceNames**: Alternative device name mappings +- **DBHelper**: Local database operations for device data + +## Device Types Supported + +The library can detect the following device types: + +- 📱 **Smartphone**: Standard Android phones +- 📟 **Tablet**: Tablets and large-screen devices +- ⌚ **Smartwatch**: Wear OS and other watch devices +- 📺 **Smart TV**: Android TV and set-top boxes +- 🚗 **Automotive**: Android Auto and car infotainment systems +- 🏠 **IoT**: Internet of Things devices +- 📖 **E-Reader**: E-book readers +- 🎮 **Gaming**: Gaming devices and consoles +- 🥽 **VR**: Virtual Reality headsets +- 📱 **Foldable**: Foldable phones and devices +- 💻 **Emulator**: Development emulators + +## Online API + +The library integrates with an online API to provide: + +- Device images +- Additional device specifications +- Device reporting capabilities +- Updated device database + +API endpoints are configurable through `DeviceInfo` object properties. + +## Caching + +Device information is automatically cached locally for: +- Improved performance +- Offline functionality +- Reduced network requests +- 30-day cache duration (configurable) + +## License + +``` +Copyright (C) 2017 Jared Rummler +Copyright (C) 2025 oxmc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## Support + +For issues and questions, please create an issue on the GitHub repository. diff --git a/demo/src/main/java/dev/oxmc/androiddeviceinfo_demo/MainActivity.kt b/demo/src/main/java/dev/oxmc/androiddeviceinfo_demo/MainActivity.kt index 77bdfee..12ac8f8 100644 --- a/demo/src/main/java/dev/oxmc/androiddeviceinfo_demo/MainActivity.kt +++ b/demo/src/main/java/dev/oxmc/androiddeviceinfo_demo/MainActivity.kt @@ -19,6 +19,8 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import coil.compose.AsyncImage +import coil.compose.AsyncImagePainter +import coil.compose.rememberAsyncImagePainter import dev.oxmc.androiddeviceinfo.DeviceInfo import dev.oxmc.androiddeviceinfo.AndroidInfo import dev.oxmc.androiddeviceinfo_demo.ui.theme.AndroidDeviceInfoTheme @@ -127,13 +129,25 @@ fun DeviceInfoScreen() { Spacer(modifier = Modifier.height(16.dp)) imageUrl?.let { - AsyncImage( - model = it, - contentDescription = "Device Image", + val painter = rememberAsyncImagePainter(model = it) + val painterState = painter.state + + Box( modifier = Modifier .size(180.dp) - .padding(8.dp) - ) + .padding(8.dp), + contentAlignment = Alignment.Center + ) { + if (painterState is AsyncImagePainter.State.Loading) { + CircularProgressIndicator() + } + + Image( + painter = painter, + contentDescription = "Device Image", + modifier = Modifier.matchParentSize() + ) + } } ?: run { Image( painter = painterResource(id = R.drawable.unknown_device), @@ -154,10 +168,10 @@ fun DeviceInfoScreen() { InfoText("Type", deviceType) InfoText("Android", androidVersion) - // If the device has no image or the information is unknown, show a message - if (imageUrl == null || deviceName == "Unknown") { + // If the device has no image, show a message + if (imageUrl == null) { Text( - text = "Unable to determine device details from the model. If you know the model or would like to upload this information to improve detection, please use the button below:", + text = "Unable to determine device image from the model. If you know the model or would like to upload this information to improve detection, please use the button below:", style = MaterialTheme.typography.bodyMedium, textAlign = TextAlign.Center ) diff --git a/docs.md b/docs.md new file mode 100644 index 0000000..a641a6b --- /dev/null +++ b/docs.md @@ -0,0 +1,389 @@ +# Android Device Info Library - API Documentation + +This document provides a comprehensive reference for all classes, functions, and properties available in the Android Device Info library. + +## Table of Contents + +- [AndroidInfo Object](#androidinfo-object) +- [DeviceInfo Object](#deviceinfo-object) +- [AndroidDeviceInfo Object](#androiddeviceinfo-object) +- [AltDeviceNames Object](#altdevicenames-object) +- [DeviceDatabase Class](#devicedatabase-class) +- [Device Types](#device-types) +- [Data Classes](#data-classes) + +--- + +## AndroidInfo Object + +The main object for accessing static device information and type detection. + +### Properties + +#### Info Object +Access to basic device information from `Build` class: + +```kotlin +AndroidInfo.Info.brand: String // Device brand (e.g., "samsung") +AndroidInfo.Info.model: String // Device model (e.g., "SM-G998U") +AndroidInfo.Info.device: String // Device name (e.g., "p3qsqw") +AndroidInfo.Info.product: String // Product name +AndroidInfo.Info.manufacturer: String // Manufacturer (e.g., "Samsung") +AndroidInfo.Info.hardware: String // Hardware name +AndroidInfo.Info.board: String // Board name +AndroidInfo.Info.fingerprint: String // Build fingerprint +``` + +#### Version Object +Access to Android version information: + +```kotlin +AndroidInfo.Version.release: String // Android version (e.g., "13") +AndroidInfo.Version.incremental: String // Incremental version +AndroidInfo.Version.sdkInt: Int // SDK version number (e.g., 33) +AndroidInfo.Version.codename: String // Version codename +``` + +#### Device Detection Properties + +```kotlin +AndroidInfo.isEmulator: Boolean // True if running on emulator +AndroidInfo.isPhysicalDevice: Boolean // True if running on physical device +``` + +### Functions + +#### getType(context: Context): DeviceType +Determines the type of device. + +**Parameters:** +- `context: Context` - Application context + +**Returns:** `DeviceType` enum value + +**Example:** +```kotlin +val deviceType = AndroidInfo.getType(context) +when (deviceType) { + AndroidInfo.DeviceType.SMARTPHONE -> // Handle smartphone + AndroidInfo.DeviceType.TABLET -> // Handle tablet + // ... other cases +} +``` + +### Vendor-Specific Objects + +Empty objects ready for future vendor-specific functionality: + +```kotlin +AndroidInfo.Samsung // Samsung-specific features +AndroidInfo.Xiaomi // Xiaomi-specific features +AndroidInfo.Oppo // Oppo-specific features +AndroidInfo.Huawei // Huawei-specific features +AndroidInfo.OnePlus // OnePlus-specific features +AndroidInfo.Vivo // Vivo-specific features +AndroidInfo.LG // LG-specific features +AndroidInfo.Lenovo // Lenovo-specific features +AndroidInfo.Sony // Sony-specific features +AndroidInfo.Google // Google Pixel-specific features +AndroidInfo.Asus // Asus-specific features +AndroidInfo.Realme // Realme-specific features +AndroidInfo.Motorola // Motorola-specific features +AndroidInfo.Nokia // Nokia-specific features +AndroidInfo.Honor // Honor-specific features +AndroidInfo.Infinix // Infinix-specific features +AndroidInfo.Tecno // Tecno-specific features +AndroidInfo.ZTE // ZTE-specific features +AndroidInfo.Meizu // Meizu-specific features +AndroidInfo.Sharp // Sharp-specific features +AndroidInfo.Micromax // Micromax-specific features +``` + +--- + +## DeviceInfo Object + +Provides async device information retrieval with online API integration. + +### Properties + +```kotlin +DeviceInfo.api_url_base: String // Base API URL (default: "https://cdn.oxmc.me/api") +DeviceInfo.api_device: String // Device API endpoint +DeviceInfo.api_deviceSearch: String // Device search endpoint +DeviceInfo.api_reportDevice: String // Device reporting endpoint +DeviceInfo.api_version: String // API version (default: "v2") +``` + +### Functions + +#### getDeviceInfo(context: Context): Array +**Suspend function** - Gets comprehensive device information including image URL. + +**Parameters:** +- `context: Context` - Application context + +**Returns:** Array containing: +- `[0]` - Device name +- `[1]` - Manufacturer +- `[2]` - Model +- `[3]` - Codename +- `[4]` - Image URL (nullable) + +**Example:** +```kotlin +lifecycleScope.launch { + val (name, manufacturer, model, codename, imageUrl) = DeviceInfo.getDeviceInfo(context) + // Use the information +} +``` + +#### getDeviceName(context: Context): String +Gets the user-configured device name or falls back to manufacturer + model. + +**Parameters:** +- `context: Context` - Application context + +**Returns:** Device name string + +**Example:** +```kotlin +val deviceName = DeviceInfo.getDeviceName(context) +``` + +#### getDeviceImage(context: Context, codename: String, model: String, manufacturer: String): String? +**Suspend function** - Fetches device image URL from API. + +**Parameters:** +- `context: Context` - Application context +- `codename: String` - Device codename +- `model: String` - Device model +- `manufacturer: String` - Device manufacturer + +**Returns:** Image URL string or null if not found + +**Example:** +```kotlin +lifecycleScope.launch { + val imageUrl = DeviceInfo.getDeviceImage(context, "p3qsqw", "SM-G998U", "Samsung") + // Load image from URL +} +``` + +#### reportDeviceInfo(context: Context, deviceName: String, manufacturer: String, model: String, codename: String): Boolean +**Suspend function** - Reports device information to the server. + +**Parameters:** +- `context: Context` - Application context +- `deviceName: String` - Device name +- `manufacturer: String` - Manufacturer +- `model: String` - Device model +- `codename: String` - Device codename + +**Returns:** True if successful, false otherwise + +--- + +## AndroidDeviceInfo Object + +Handles device name resolution and caching. + +### Functions + +#### getCurrentDeviceInfo(context: Context): DeviceInfo +**Worker thread function** - Gets current device information with caching. + +**Parameters:** +- `context: Context` - Application context (nullable) + +**Returns:** `DeviceInfo` data class instance + +**Example:** +```kotlin +// Call from background thread +val deviceInfo = AndroidDeviceInfo.getCurrentDeviceInfo(context) +``` + +--- + +## AltDeviceNames Object + +Provides alternative device name mappings for known devices. + +### Functions + +#### getAlternateNameOrDefault(model: String, manufacturer: String, codename: String, default: String): String +Gets alternative device name or returns default. + +**Parameters:** +- `model: String` - Device model +- `manufacturer: String` - Device manufacturer +- `codename: String` - Device codename +- `default: String` - Default name if no alternative found + +**Returns:** Alternative device name or default + +**Example:** +```kotlin +val alternateName = AltDeviceNames.getAlternateNameOrDefault( + "SM-G998U", + "Samsung", + "p3qsqw", + "Galaxy S21 Ultra" +) +``` + +#### containsIdentifier(model: String, manufacturer: String, codename: String): Boolean +Checks if device identifiers exist in the alternate names database. + +**Parameters:** +- `model: String` - Device model +- `manufacturer: String` - Device manufacturer +- `codename: String` - Device codename + +**Returns:** True if identifiers are found, false otherwise + +--- + +## DeviceDatabase Class + +SQLite database helper for device information storage. + +### Constructor + +```kotlin +DeviceDatabase(context: Context, autoUpdateDB: Boolean = true) +``` + +**Parameters:** +- `context: Context` - Application context +- `autoUpdateDB: Boolean` - Whether to automatically update database (default: true) + +### Functions + +#### queryToDevice(codename: String, model: String): DeviceInfo? +Queries the database for device information. + +**Parameters:** +- `codename: String` - Device codename +- `model: String` - Device model + +**Returns:** `DeviceInfo` object or null if not found + +#### close() +Closes the database connection. + +**Example:** +```kotlin +DeviceDatabase(context).use { database -> + val deviceInfo = database.queryToDevice("p3qsqw", "SM-G998U") + // Use deviceInfo +} +``` + +--- + +## Device Types + +### DeviceType Enum + +```kotlin +enum class DeviceType { + EMULATOR, // Development emulator + SMARTPHONE, // Standard phone + TABLET, // Tablet device + SMARTWATCH, // Wearable device + SMART_TV, // TV or set-top box + AUTOMOTIVE, // Car infotainment + IOT, // Internet of Things device + EREADER, // E-book reader + GAMING, // Gaming device/console + VR, // Virtual Reality headset + FOLDABLE // Foldable device +} +``` + +### Device Type Detection Logic + +The library uses the following criteria to determine device types: + +- **EMULATOR**: Checks build fingerprint, model, manufacturer, and hardware for emulator indicators +- **SMARTWATCH**: Device name starts with "wear", "smartwatch", "watch", or "wrist" +- **SMART_TV**: Device name starts with "tv", "television", "settopbox", "streaming", "media", or "dongle" +- **AUTOMOTIVE**: Device name starts with "car", "automotive", "infotainment", "dashboard", "headunit", or "vehicle" +- **IOT**: Device name starts with "iot", "smart", "connected", "home", "appliance", or "device" +- **EREADER**: Device name starts with "ereader", "ebook", "tablet", or "kindle" +- **GAMING**: Device name starts with "gaming", "console", "handheld", or "portable" +- **VR**: Device name starts with VR-related terms or "quest", "oculus", "meta", "rift" +- **FOLDABLE**: Device name starts with "fold", "flip", "clamshell", "booklet", "dual", or "trifold" +- **TABLET**: Screen smallest width >= 600dp OR model contains "tab" +- **SMARTPHONE**: Default fallback for mobile devices + +--- + +## Data Classes + +### DeviceInfo Data Class + +```kotlin +class DeviceInfo( + val manufacturer: String?, // Device manufacturer + val marketName: String?, // Market/commercial name + val codename: String, // Internal codename + val model: String, // Model identifier + val timestamp: Long = 0 // Cache timestamp +) { + val name: String // Computed property: marketName or capitalized model +} +``` + +**Properties:** +- `manufacturer`: Device manufacturer (e.g., "Samsung") +- `marketName`: Commercial device name (e.g., "Galaxy S21 Ultra") +- `codename`: Internal device code (e.g., "p3qsqw") +- `model`: Model identifier (e.g., "SM-G998U") +- `timestamp`: When the information was cached +- `name`: The display name (marketName if available, otherwise capitalized model) + +### Alternative Constructor + +```kotlin +DeviceInfo(jsonObject: JSONObject, timestamp: Long) +``` + +Creates DeviceInfo from cached JSON data. + +--- + +## Error Handling + +Most functions handle errors gracefully: + +- Network operations return null or false on failure +- Database operations fall back to alternate name resolution +- Type detection defaults to SMARTPHONE for unknown devices +- Caching operations ignore JSON parsing errors + +## Thread Safety + +- **AndroidInfo**: Thread-safe (uses lazy initialization) +- **DeviceInfo**: Use suspend functions from coroutine scope +- **AndroidDeviceInfo.getCurrentDeviceInfo()**: Must be called from worker thread +- **DeviceDatabase**: Not thread-safe, use appropriate synchronization + +## Performance Considerations + +- Device information is cached locally for 30 days +- Network requests have 5-second timeouts +- Database queries are optimized for common device lookups +- Lazy initialization used for expensive operations + +## API Configuration + +You can customize API endpoints: + +```kotlin +DeviceInfo.api_url_base = "https://your-api.com" +DeviceInfo.api_version = "v3" +// Other endpoints will be constructed based on these values +```