Files
NeoTerm_System/app/src/main/java/io/neoterm/utils/utils.kt

124 lines
4.6 KiB
Kotlin
Raw Normal View History

2021-05-08 13:42:17 +08:00
package io.neoterm.utils
import android.content.ContentUris
import android.content.Context
import android.net.Uri
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
2021-05-08 16:41:20 +08:00
import io.neoterm.R
2021-05-08 13:42:17 +08:00
import io.neoterm.frontend.config.NeoTermPath
import io.neoterm.frontend.floating.TerminalDialog
import java.io.File
import java.nio.file.Files
import java.text.DecimalFormat
class RangedInt(private val number: Int, private val range: IntRange) {
fun inc() = (number + 1).takeIf { range.contains(it) } ?: 0
fun dec() = (number - 1).takeIf { range.contains(it) } ?: range.last
}
fun Long.formatSizeInKB(): String {
val decimalFormat = DecimalFormat("####.00");
if (this < 1024) {
return "$this KB"
} else if (this < 1024 * 1024) {
val parsedSize: Float = this / 1024f
return decimalFormat.format(parsedSize) + " MB"
} else if (this < 1024 * 1024 * 1024) {
val parsedSize: Float = this / 1024f / 1024f
return decimalFormat.format(parsedSize) + " GB"
} else if (this < 1024L * 1024 * 1024 * 1024) {
val parsedSize: Float = this / 1024f / 1024f / 1024f
return decimalFormat.format(parsedSize) + " TB"
} else {
return "$this KB"
}
}
fun Context.extractAssetsDir(dirName: String, extractDir: String) {
val assets = this.assets
assets.list(dirName)?.let {
it.map { File(extractDir, it) }
.takeWhile { !it.exists() }
.forEach { file ->
assets.open("$dirName/${file.name}").use {
kotlin.runCatching { Files.copy(it, file.toPath()) }
}
}
}
}
2021-05-08 16:41:20 +08:00
fun Context.runApt(
subCommand: String, vararg extraArgs: String,
autoClose: Boolean = true, block: (Result<TerminalDialog>) -> Unit
) = TerminalDialog(this)
.execute(NeoTermPath.APT_BIN_PATH, arrayOf(NeoTermPath.APT_BIN_PATH, subCommand, *extraArgs))
.imeEnabled(true)
.onFinish { dialog, session ->
val exit = session?.exitStatus ?: 1
if (exit == 0) {
if (autoClose) dialog.dismiss()
block(Result.success(dialog))
} else {
dialog.setTitle(getString(R.string.error))
block(Result.failure(RuntimeException()))
}
}
.show("apt $subCommand")
2021-05-08 13:42:17 +08:00
/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.
* @param context The context.
* @param inUri The Uri to query.
*/
fun Context.getPathOfMediaUri(inUri: Uri?) = inUri?.let {
when {
"content".equals(it.scheme, ignoreCase = true) -> getDataColumn(this, it, null, null)
"file".equals(it.scheme, ignoreCase = true) -> it.path
DocumentsContract.isDocumentUri(this, it) -> this.getPathOfDocumentUri(it)
else -> null
}
}
private fun Context.getPathOfDocumentUri(uri: Uri) = if (isExternalStorageDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]
if ("primary".equals(type, ignoreCase = true)) Environment.getExternalStorageDirectory().toString() + "/" + split[1]
else "/storage/$type/${split[1]}" // Temporary workaround for non-primary volumes
} else if (isDownloadsDocument(uri)) {
val id = DocumentsContract.getDocumentId(uri)
val contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id)
)
getDataColumn(this, contentUri, null, null)
} else if (isMediaDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val contentUri = when (split[0]) {
"image" -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
"video" -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
"audio" -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
else -> null
}
getDataColumn(this, contentUri!!, "_id=?", arrayOf(split[1]))
} else null
/**
* Get the value of the data column for this Uri
*/
private fun getDataColumn(context: Context, uri: Uri, selection: String?, selectionArgs: Array<String>?) =
context.contentResolver.query(uri, arrayOf("_data"), selection, selectionArgs, null)?.use {
if (it.moveToFirst()) {
val columnIndex = it.getColumnIndex("_data").takeIf { it != -1 } ?: return@use null
it.getString(columnIndex)
} else null
}
private fun isExternalStorageDocument(uri: Uri) = "com.android.externalstorage.documents" == uri.authority
private fun isDownloadsDocument(uri: Uri) = "com.android.providers.downloads.documents" == uri.authority
private fun isMediaDocument(uri: Uri) = "com.android.providers.media.documents" == uri.authority