Dev: File & Storage Management
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/java/com/musagenius/ocrapp/data/utils/StorageManager.kt
- app/src/main/res/xml/file_paths.xml
- app/src/main/AndroidManifest.xml
- app/src/main/java/com/musagenius/ocrapp/data/ocr/OCRServiceImpl.kt
- app/src/main/java/com/musagenius/ocrapp/domain/usecase/DeleteLanguageUseCase.kt
- ROADMAP.md
- TODO.md
- app/src/main/assets/tessdata/README.md
The file and storage management system is designed for an offline-first experience, ensuring all user data, captured images, and OCR language models are stored and processed on the device. The core of this system is the StorageManager utility, which handles storage capacity checks, usage calculations, and automated cleanup.
The application manages three primary types of data: captured images, the Room database for scan metadata, and Tesseract's .traineddata language files. Captured images and language files are stored in the app's external files directory, while temporary data resides in the cache directory. A FileProvider is used to securely expose file URIs to other applications for sharing purposes. The overall strategy, as outlined in the project roadmap, aims to prevent uncontrolled storage growth through proactive checks, cleanup policies, and user-facing management tools.
Sources: app/src/main/java/com/musagenius/ocrapp/data/utils/StorageManager.kt, ROADMAP.md, app/src/main/AndroidManifest.xml
StorageManager Utility
The StorageManager is a Hilt @Singleton class that centralizes all storage-related operations. It provides functionalities to query device storage status, calculate the app's storage footprint, and perform cleanup tasks.
Sources: app/src/main/java/com/musagenius/ocrapp/data/utils/StorageManager.kt:15-20
This diagram shows the structure of the StorageManager and its associated data class StorageInfo.
Key Methods
| Method | Description |
|---|---|
hasAvailableStorage(requiredMB) | Checks if the available storage meets a minimum requirement. Defaults to 100MB. |
calculateAppStorageUsage() | Asynchronously calculates the total storage used by the app by summing the size of the external files directory and the cache directory. Returns a StorageInfo object. |
cleanupOldFiles(maxAgeDays) | Deletes files in the external directory older than a specified number of days (default is 7) and prefixed with compressed_. |
clearCache() | Recursively deletes all files and subdirectories within the app's cache directory. |
getAvailableStorageMB() | Returns the available storage space in megabytes on the device's external storage. |
Sources: app/src/main/java/com/musagenius/ocrapp/data/utils/StorageManager.kt:28-115
Automated File Cleanup
The cleanupOldFiles function provides a mechanism to automatically purge temporary or old files. It operates on the app's external files directory.
The following flowchart illustrates the logic of the cleanupOldFiles function.
// app/src/main/java/com/musagenius/ocrapp/data/utils/StorageManager.kt:118-137
suspend fun cleanupOldFiles(maxAgeDays: Int = TEMP_FILE_MAX_AGE_DAYS): Int = withContext(Dispatchers.IO) {
try {
val externalDir = context.getExternalFilesDir(null) ?: return@withContext 0
val cutoffTime = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(maxAgeDays.toLong())
var deletedCount = 0
externalDir.listFiles()?.forEach { file ->
if (file.isFile && file.lastModified() < cutoffTime && file.name.startsWith("compressed_")) {
if (file.delete()) {
deletedCount++
Log.d(TAG, "Deleted old file: ${file.name}")
}
}
}
Log.d(TAG, "Cleanup complete: deleted $deletedCount files")
deletedCount
} catch (e: Exception) {
Log.e(TAG, "Error during cleanup", e)
0
}
}
Tesseract Language Data Management
The app manages Tesseract's .traineddata files, which are required for OCR. These files are bundled in the assets/tessdata directory and are copied to the app's external storage on-demand.
Sources: app/src/main/java/com/musagenius/ocrapp/data/ocr/OCRServiceImpl.kt:190-213, app/src/main/assets/tessdata/README.md
Language File Initialization
When the OCRServiceImpl is initialized for a specific language, it checks if the corresponding .traineddata file exists in the app's external storage (<external_files_dir>/tessdata). If the file is not present, it is copied from the app's assets.
This sequence diagram shows the process of copying a language file from assets when OCR is initiated.
Language File Deletion
The DeleteLanguageUseCase provides a mechanism to remove downloaded language files to free up space. It prevents the deletion of the default English (eng) language file.
Sources: app/src/main/java/com/musagenius/ocrapp/domain/usecase/DeleteLanguageUseCase.kt:25-31
File Sharing & Permissions
The application uses a FileProvider to securely share files, such as captured images, with other apps. This prevents FileUriExposedException on Android 7.0 (API 24) and higher.
Sources: app/src/main/AndroidManifest.xml:41-48
FileProvider Configuration
The FileProvider is declared in the manifest and configured via an XML resource file that specifies the shareable paths.
Manifest Declaration:
<!-- app/src/main/AndroidManifest.xml:41-48 -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
Shareable Paths (file_paths.xml):
The app exposes its external files directory, allowing files within it to be shared.
<!-- app/src/main/res/xml/file_paths.xml:2-6 -->
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path
name="my_images"
path="." />
</paths>
Sources: app/src/main/res/xml/file_paths.xml
Storage Permissions
The application requests several permissions to handle camera access and file storage across different Android versions.
| Permission | Max SDK Version | Purpose |
|---|---|---|
android.permission.CAMERA | - | To access the device camera for scanning. |
android.permission.READ_EXTERNAL_STORAGE | 32 | To read images from shared storage on older Android versions. |
android.permission.WRITE_EXTERNAL_STORAGE | 28 | To save files to shared storage on older Android versions. |
android.permission.READ_MEDIA_IMAGES | - | To read images from the media store on Android 13+ (Scoped Storage). |
Sources: app/src/main/AndroidManifest.xml:13-20
Storage Management Strategy
The project's roadmap outlines a comprehensive strategy to manage storage consumption and prevent the app from using excessive disk space.
Key mitigation plans include:
- Storage Checks: Before capturing an image, the app will check for available storage and warn the user if it falls below a 100MB threshold.
- Image Compression: Captured images will be automatically compressed (e.g., JPEG at 85% quality) to reduce file size.
- User-Facing Management: A UI will be provided to show a breakdown of storage usage (images, database, language files) and allow for bulk deletion of old scans.
- Language Data Limits: The number of installed language packs may be limited, and a mechanism to delete unused language files is planned.
- Auto-Cleanup Policies: A user-configurable setting to automatically delete scans older than a certain number of days (e.g., 90 days) is part of the long-term plan.
Sources: ROADMAP.md, TODO.md
Conclusion
The file and storage management system in this OCR app is built to be robust and self-sufficient for an offline-first architecture. The StorageManager class provides essential utilities for monitoring and cleaning up storage. Tesseract language files are handled efficiently by copying them on-demand and providing a use case for their deletion. Secure file sharing is implemented using a FileProvider, and the application adheres to modern storage permission practices. The project's roadmap demonstrates a clear, forward-thinking strategy for long-term storage management to ensure a good user experience.
Sources: app/src/main/java/com/musagenius/ocrapp/data/utils/StorageManager.kt, ROADMAP.md, app/src/main/java/com/musagenius/ocrapp/data/ocr/OCRServiceImpl.kt