blob: 16777de7a658c9c25f6a5f055dde6b59c213572d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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
}
}
|