Uri.kt
package chat.rocket.android.util.extensions
import android.annotation.TargetApi
import android.app.Activity
import android.content.ContentResolver
import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.provider.OpenableColumns
import android.webkit.MimeTypeMap
import chat.rocket.android.R
import chat.rocket.android.authentication.domain.model.*
import timber.log.Timber
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.IOException
import java.io.InputStream
fun Uri.getFileName(context: Context): String? {
val cursor = context.contentResolver.query(this, null, null, null, null, null)
var fileName: String? = null
cursor?.use {
if (it.moveToFirst()) {
fileName = it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME))
}
}
return fileName
}
fun Uri.getFileSize(context: Context): Int {
var fileSize: String? = null
if (scheme == ContentResolver.SCHEME_CONTENT) {
try {
val fileInputStream = context.contentResolver.openInputStream(this)
fileSize = fileInputStream?.available().toString()
} catch (e: Exception) {
e.printStackTrace()
}
} else if (scheme == ContentResolver.SCHEME_FILE) {
val path = this.path
try {
val f = File(path)
fileSize = f.length().toString()
} catch (e: Exception) {
e.printStackTrace()
}
}
return fileSize?.toIntOrNull() ?: -1
}
fun Uri.getMimeType(context: Context): String {
return if (scheme == ContentResolver.SCHEME_CONTENT) {
context.contentResolver?.getType(this) ?: ""
} else {
val fileExtension = MimeTypeMap.getFileExtensionFromUrl(toString())
if (fileExtension != null) {
MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension.toLowerCase())
} else {
"application/octet-stream"
}
}
}
@TargetApi(Build.VERSION_CODES.N)
fun Uri.isVirtualFile(context: Context): Boolean {
if (!DocumentsContract.isDocumentUri(context, this)) {
return false
}
val cursor = context.contentResolver.query(
this,
arrayOf(DocumentsContract.Document.COLUMN_FLAGS),
null,
null,
null
)
var flags = 0
cursor?.use {
if (it.moveToFirst()) {
flags = it.getInt(0)
}
}
return flags and DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT != 0
}
@Throws(IOException::class)
fun Uri.getInputStreamForVirtualFile(context: Context, mimeTypeFilter: String): FileInputStream? {
val resolver = context.contentResolver
val openableMimeTypes = resolver.getStreamTypes(this, mimeTypeFilter)
if (openableMimeTypes == null || openableMimeTypes.isEmpty()) {
throw FileNotFoundException()
}
return resolver.openTypedAssetFileDescriptor(this, openableMimeTypes[0], null)
?.createInputStream()
}
fun Uri.getInputStream(context: Context): InputStream? {
if (isVirtualFile(context)) {
return getInputStreamForVirtualFile(context, "*/*")
}
return context.contentResolver.openInputStream(this)
}
fun Uri.getBitmpap(context: Context): Bitmap? {
return MediaStore.Images.Media.getBitmap(context.contentResolver, this)
}
fun Uri.getDeepLinkInfo(context: Context): DeepLinkInfo? {
return when {
isAuthenticationDeepLink(context) -> {
val host = getQueryParameter("host")
val url = if (host.startsWith("http")) host else "https://$host"
val userId = getQueryParameter("userId")
val token = getQueryParameter("token")
try {
DeepLinkInfo(url, userId, token, null, null, null)
} catch (ex: Exception) {
Timber.d(ex, "Error parsing auth deeplink")
null
}
}
isCustomSchemeRoomLink() -> {
val hostValue = getQueryParameter("host")
val url = if (hostValue.startsWith("http")) hostValue else "https://$hostValue"
val rid = getQueryParameter("rid")
val pathValue = getQueryParameter("path")
val pathSplit = pathValue.split("/")
val roomType = pathSplit[0]
val roomName = pathSplit[1]
try {
DeepLinkInfo(url, null, null, rid, roomType, roomName)
} catch (ex: Exception) {
Timber.d(ex, "Error parsing custom scheme room link")
null
}
}
isWebSchemeRoomLink() -> {
val url = "https://$host"
val pathSplit = path.split("/")
val roomType = pathSplit[1]
val roomName = pathSplit[2]
try {
DeepLinkInfo(url, null, null, null, roomType, roomName)
} catch (ex: Exception) {
Timber.d(ex, "Error parsing login deeplink")
null
}
}
else -> null
}
}
fun Uri.isDynamicLink(activity: Activity): Boolean {
return (host != null && host.contains(activity.getString(R.string.dynamic_link_host_url)))
}
// Authentication deep link defined here: https://rocket.chat/docs/developer-guides/deeplink/#authentication
fun Uri.isAuthenticationDeepLink(context: Context): Boolean {
if (host == "auth")
return true
else if (host == context.getString(R.string.community_server_url) && path == "/auth")
return true
return false
}
// Custom scheme room deep link defined here: https://rocket.chat/docs/developer-guides/deeplink/#channel--group--dm
fun Uri.isCustomSchemeRoomLink(): Boolean {
if (scheme.startsWith("rocketchat") &&
host == "room")
return true
return false
}
// http(s) scheme deep link not yet documented. Ex: https://open.rocket.chat/direct/testuser1
fun Uri.isWebSchemeRoomLink(): Boolean {
val roomType = path.split("/")[1]
if (scheme.startsWith("http") &&
(roomType == "channel" || roomType == "group" || roomType == "direct"))
return true
return false
}