diff options
Diffstat (limited to 'androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/FileCache.kt')
-rw-r--r-- | androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/FileCache.kt | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/FileCache.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/FileCache.kt new file mode 100644 index 0000000..16777de --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/FileCache.kt @@ -0,0 +1,120 @@ +package mx.trackermap.TrackerMap.android.shared + +import android.content.Context +import android.net.Uri +import android.provider.OpenableColumns +import android.webkit.MimeTypeMap +import java.io.BufferedInputStream +import java.io.BufferedOutputStream +import java.io.File +import java.io.FileOutputStream + +// Source: https://techenum.com/android-content-uri-how-to-get-the-file-uri/ +class FileCache( + private val context: Context +) { + + // content resolver + private val contentResolver = context.contentResolver + + // to get the type of file + private val mimeTypeMap = MimeTypeMap.getSingleton() + + private val mCacheLocation = File(context.cacheDir, "reports_tmp") + + fun cacheThis(uris: List<Uri>) { + uris.forEach { uri -> copyFromSource(uri) } + } + + /** + * Copies the actual data from provided content provider. + */ + private fun copyFromSource(uri: Uri) { + + val fileExtension: String = getFileExtension(uri) ?: kotlin.run { + throw RuntimeException("Extension is null for $uri") + } + val fileName = queryName(uri) ?: getFileName(fileExtension) + + val inputStream = contentResolver.openInputStream(uri) ?: kotlin.run { + throw RuntimeException("Cannot open for reading $uri") + } + val bufferedInputStream = BufferedInputStream(inputStream) + + // the file which will be the new cached file + val outputFile = File(mCacheLocation, fileName) + if (!outputFile.exists()) { + outputFile.parentFile?.mkdirs() + } else { + outputFile.delete() + } + val bufferedOutputStream = BufferedOutputStream(FileOutputStream(outputFile)) + + // this will hold the content for each iteration + val buffer = ByteArray(DEFAULT_BUFFER_SIZE) + + var readBytes: Int // will be -1 if reached the end of file + + while (true) { + readBytes = bufferedInputStream.read(buffer) + + // check if the read was failure + if (readBytes == -1) { + bufferedOutputStream.flush() + break + } + + bufferedOutputStream.write(buffer) + bufferedOutputStream.flush() + } + + // close everything + inputStream.close() + bufferedInputStream.close() + bufferedOutputStream.close() + + } + + private fun getFileExtension(uri: Uri): String? { + return mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(uri)) + } + + /** + * Tries to get actual name of the file being copied. + * This might be required in some of the cases where you might want to know the file name too. + * + * @param uri + * + */ + private fun queryName(uri: Uri): String? { + val returnCursor = contentResolver.query(uri, null, null, null, null) ?: return null + val nameIndex: Int = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) + returnCursor.moveToFirst() + val name: String = returnCursor.getString(nameIndex) + returnCursor.close() + return name + } + + private fun getFileName(fileExtension: String): String { + return "${System.currentTimeMillis()}.$fileExtension" + } + + /** + * Remove everything that we have cached. + * You might want to invoke this method before quiting the application. + */ + fun removeAll() { + mCacheLocation.deleteRecursively() + } + + companion object { + + // base buffer size + private const val BASE_BUFFER_SIZE = 1024 + + // if you want to modify size use binary multiplier 2, 4, 6, 8 + private const val DEFAULT_BUFFER_SIZE = BASE_BUFFER_SIZE * 4 + + } + +}
\ No newline at end of file |