Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
AloqaIM-Android
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
AloqaIM-Android
Commits
20b14673
Commit
20b14673
authored
Feb 15, 2018
by
Lucio Maciel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve file upload. Respect FileUpload_MediaTypeWhiteList and FileUpload_MaxFileSize
parent
befa16fc
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
233 additions
and
155 deletions
+233
-155
ServerPresenter.kt
...oid/authentication/server/presentation/ServerPresenter.kt
+19
-44
UriInteractor.kt
...java/chat/rocket/android/chatroom/domain/UriInteractor.kt
+4
-27
ChatRoomPresenter.kt
...rocket/android/chatroom/presentation/ChatRoomPresenter.kt
+17
-23
ChatRoomView.kt
...chat/rocket/android/chatroom/presentation/ChatRoomView.kt
+7
-0
ChatRoomFragment.kt
.../java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
+11
-7
ChatRoomsPresenter.kt
...cket/android/chatrooms/presentation/ChatRoomsPresenter.kt
+3
-0
RefreshSettingsInteractor.kt
...rocket/android/server/domain/RefreshSettingsInteractor.kt
+40
-0
SettingsRepository.kt
...a/chat/rocket/android/server/domain/SettingsRepository.kt
+17
-1
Collections.kt
...n/java/chat/rocket/android/util/extensions/Collections.kt
+8
-0
Text.kt
...src/main/java/chat/rocket/android/util/extensions/Text.kt
+1
-53
Uri.kt
app/src/main/java/chat/rocket/android/util/extensions/Uri.kt
+103
-0
strings.xml
app/src/main/res/values/strings.xml
+3
-0
No files found.
app/src/main/java/chat/rocket/android/authentication/server/presentation/ServerPresenter.kt
View file @
20b14673
...
...
@@ -4,66 +4,41 @@ import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import
chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.helper.NetworkHelper
import
chat.rocket.android.helper.UrlHelper
import
chat.rocket.android.server.domain.
*
import
chat.rocket.android.server.
infraestructure.RocketChatClientFactory
import
chat.rocket.android.server.domain.
RefreshSettingsInteractor
import
chat.rocket.android.server.
domain.SaveCurrentServerInteractor
import
chat.rocket.android.util.extensions.launchUI
import
chat.rocket.common.util.ifNull
import
chat.rocket.core.RocketChatClient
import
chat.rocket.core.internal.rest.settings
import
java.security.InvalidParameterException
import
javax.inject.Inject
class
ServerPresenter
@Inject
constructor
(
private
val
view
:
ServerView
,
private
val
strategy
:
CancelStrategy
,
private
val
navigator
:
AuthenticationNavigator
,
private
val
serverInteractor
:
SaveCurrentServerInteractor
,
private
val
settingsInteractor
:
SaveSettingsInteractor
,
private
val
factory
:
RocketChatClientFactory
)
{
private
lateinit
var
client
:
RocketChatClient
private
var
settingsFilter
=
arrayOf
(
SITE_URL
,
SITE_NAME
,
FAVICON_512
,
USE_REALNAME
,
ALLOW_ROOM_NAME_SPECIAL_CHARS
,
FAVORITE_ROOMS
,
ACCOUNT_LOGIN_FORM
,
ACCOUNT_GOOGLE
,
ACCOUNT_FACEBOOK
,
ACCOUNT_GITHUB
,
ACCOUNT_GITLAB
,
ACCOUNT_LINKEDIN
,
ACCOUNT_METEOR
,
ACCOUNT_TWITTER
,
ACCOUNT_WORDPRESS
,
LDAP_ENABLE
,
ACCOUNT_REGISTRATION
,
STORAGE_TYPE
,
HIDE_USER_JOIN
,
HIDE_USER_LEAVE
,
HIDE_TYPE_AU
,
HIDE_MUTE_UNMUTE
,
HIDE_TYPE_RU
,
ACCOUNT_CUSTOM_FIELDS
,
ALLOW_MESSAGE_DELETING
,
ALLOW_MESSAGE_EDITING
,
ALLOW_MESSAGE_PINNING
,
SHOW_DELETED_STATUS
,
SHOW_EDITED_STATUS
)
private
val
refreshSettingsInteractor
:
RefreshSettingsInteractor
)
{
fun
connect
(
server
:
String
)
{
if
(!
UrlHelper
.
isValidUrl
(
server
))
{
view
.
showInvalidServerUrl
()
}
else
{
try
{
client
=
factory
.
create
(
server
)
}
catch
(
exception
:
InvalidParameterException
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
return
}
client
.
let
{
rocketChatClient
->
launchUI
(
strategy
)
{
if
(
NetworkHelper
.
hasInternetAccess
())
{
view
.
showLoading
()
launchUI
(
strategy
)
{
if
(
NetworkHelper
.
hasInternetAccess
())
{
view
.
showLoading
()
try
{
val
settings
=
rocketChatClient
.
settings
(*
settingsFilter
)
settingsInteractor
.
save
(
server
,
settings
)
serverInteractor
.
save
(
server
)
try
{
refreshSettingsInteractor
.
refresh
(
server
)
serverInteractor
.
save
(
server
)
navigator
.
toLogin
()
}
catch
(
exception
:
Exception
)
{
exception
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
finally
{
view
.
hideLoading
()
navigator
.
toLogin
()
}
catch
(
ex
:
Exception
)
{
ex
.
message
?.
let
{
view
.
showMessage
(
it
)
}.
ifNull
{
view
.
showGenericErrorMessage
()
}
}
else
{
view
.
showNoInternetConnection
()
}
finally
{
view
.
hideLoading
()
}
}
else
{
view
.
showNoInternetConnection
()
}
}
}
...
...
app/src/main/java/chat/rocket/android/chatroom/domain/UriInteractor.kt
View file @
20b14673
...
...
@@ -2,11 +2,7 @@ package chat.rocket.android.chatroom.domain
import
android.content.Context
import
android.net.Uri
import
chat.rocket.android.util.extensions.getFileName
import
chat.rocket.android.util.extensions.getMimeType
import
chat.rocket.android.util.extensions.getRealPathFromURI
import
okio.Okio
import
java.io.File
import
chat.rocket.android.util.extensions.*
import
javax.inject.Inject
...
...
@@ -28,26 +24,7 @@ class UriInteractor @Inject constructor(private val context: Context) {
*/
fun
getRealPath
(
uri
:
Uri
):
String
?
=
uri
.
getRealPathFromURI
(
context
)
/**
* Save the contents of an [Uri] to a temp file named after uri.getFileName()
*/
fun
tempFile
(
uri
:
Uri
):
File
?
{
try
{
val
outputDir
=
context
.
cacheDir
// context being the Activity pointer
val
outputFile
=
File
(
outputDir
,
uri
.
getFileName
(
context
))
val
from
=
context
.
contentResolver
.
openInputStream
(
uri
)
Okio
.
source
(
from
).
use
{
a
->
Okio
.
buffer
(
Okio
.
sink
(
outputFile
)).
use
{
b
->
b
.
writeAll
(
a
)
b
.
close
()
}
a
.
close
()
}
return
outputFile
}
catch
(
ex
:
Exception
)
{
ex
.
printStackTrace
()
return
null
}
}
fun
getFileSize
(
uri
:
Uri
)
=
uri
.
getFileSize
(
context
)
fun
getInputStream
(
uri
:
Uri
)
=
uri
.
getInputStream
(
context
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt
View file @
20b14673
...
...
@@ -24,7 +24,6 @@ import kotlinx.coroutines.experimental.async
import
kotlinx.coroutines.experimental.channels.Channel
import
kotlinx.coroutines.experimental.launch
import
timber.log.Timber
import
java.io.File
import
javax.inject.Inject
class
ChatRoomPresenter
@Inject
constructor
(
private
val
view
:
ChatRoomView
,
...
...
@@ -38,7 +37,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
private
val
mapper
:
MessageViewModelMapper
)
{
private
val
client
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
var
subId
:
String
?
=
null
private
va
r
settings
:
Map
<
String
,
Value
<
Any
>>
=
getSettingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
!!
private
va
l
settings
:
Map
<
String
,
Value
<
Any
>>
=
getSettingsInteractor
.
get
(
serverInteractor
.
get
()
!!
)
!!
private
val
stateChannel
=
Channel
<
State
>()
...
...
@@ -93,32 +92,28 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}
}
fun
selectFile
()
{
view
.
showFileSelection
(
settings
.
uploadMimeTypeFilter
())
}
fun
uploadFile
(
roomId
:
String
,
uri
:
Uri
,
msg
:
String
)
{
launchUI
(
strategy
)
{
view
.
showLoading
()
var
tempFile
:
File
?
=
null
try
{
val
fileName
=
async
{
uriInteractor
.
getFileName
(
uri
)
}.
await
()
val
mimeType
=
async
{
uriInteractor
.
getMimeType
(
uri
)
}.
await
()
/* FIXME - this is a workaround for uploading files with the SDK
*
* https://developer.android.com/guide/topics/providers/document-provider.html
*
* We need to use contentResolver.openInputStream(uri) to open this file.
* Since the SDK is not Android specific we cannot pass the Uri and let the
* SDK handle the file.
*
* As a temporary workaround we are saving the contents to a temp file.
*
* A proper solution is to implement some interface to open the InputStream
* and use a RequestBody based on https://github.com/square/okhttp/issues/3585
*/
tempFile
=
async
{
uriInteractor
.
tempFile
(
uri
)
}.
await
()
val
fileSize
=
async
{
uriInteractor
.
getFileSize
(
uri
)
}.
await
()
val
maxFileSize
=
settings
.
uploadMaxFileSize
()
if
(
fileName
==
null
||
tempFile
==
null
)
{
view
.
showInvalidFileMessage
()
}
else
{
client
.
uploadFile
(
roomId
,
tempFile
,
mimeType
,
msg
,
fileName
)
when
{
fileName
.
isNullOrEmpty
()
->
view
.
showInvalidFileMessage
()
fileSize
>
maxFileSize
->
view
.
showInvalidFileSize
(
fileSize
,
maxFileSize
)
else
->
{
Timber
.
d
(
"Uploading to $roomId: $fileName - $mimeType"
)
client
.
uploadFile
(
roomId
,
fileName
!!
,
mimeType
,
msg
,
description
=
fileName
)
{
uriInteractor
.
getInputStream
(
uri
)
}
}
}
}
catch
(
ex
:
RocketChatException
)
{
Timber
.
d
(
ex
)
...
...
@@ -128,13 +123,12 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
view
.
showGenericErrorMessage
()
}
}
finally
{
tempFile
?.
delete
()
view
.
hideLoading
()
}
}
}
fun
subscribeMessages
(
roomId
:
String
)
{
private
fun
subscribeMessages
(
roomId
:
String
)
{
client
.
addStateChannel
(
stateChannel
)
launch
(
CommonPool
+
strategy
.
jobs
)
{
for
(
status
in
stateChannel
)
{
...
...
app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomView.kt
View file @
20b14673
...
...
@@ -21,6 +21,11 @@ interface ChatRoomView : LoadingView, MessageView {
*/
fun
sendMessage
(
text
:
String
)
/**
* Perform file selection with the mime type [filter]
*/
fun
showFileSelection
(
filter
:
Array
<
String
>)
/**
* Uploads a file to a chat room.
*
...
...
@@ -78,4 +83,6 @@ interface ChatRoomView : LoadingView, MessageView {
fun
disableMessageInput
()
fun
enableMessageInput
(
clear
:
Boolean
=
false
)
fun
showInvalidFileSize
(
fileSize
:
Int
,
maxFileSize
:
Int
)
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatroom/ui/ChatRoomFragment.kt
View file @
20b14673
...
...
@@ -214,7 +214,17 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
text_message
.
textContent
=
text
editingMessageId
=
messageId
}
}
override
fun
showFileSelection
(
filter
:
Array
<
String
>)
{
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
)
intent
.
type
=
"*/*"
intent
.
putExtra
(
Intent
.
EXTRA_MIME_TYPES
,
filter
)
startActivityForResult
(
intent
,
REQUEST_CODE_FOR_PERFORM_SAF
)
}
override
fun
showInvalidFileSize
(
fileSize
:
Int
,
maxFileSize
:
Int
)
{
showMessage
(
getString
(
R
.
string
.
max_file_size_exceeded
,
fileSize
,
maxFileSize
))
}
private
fun
setupComposer
()
{
...
...
@@ -258,7 +268,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
button_files
.
setOnClickListener
{
handler
.
postDelayed
({
p
erformSAF
()
p
resenter
.
selectFile
()
},
300
)
handler
.
postDelayed
({
...
...
@@ -297,10 +307,4 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
view_dim
.
setVisible
(
false
)
}
private
fun
performSAF
()
{
val
intent
=
Intent
(
Intent
.
ACTION_GET_CONTENT
)
intent
.
type
=
"*/*"
startActivityForResult
(
intent
,
REQUEST_CODE_FOR_PERFORM_SAF
)
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/chatrooms/presentation/ChatRoomsPresenter.kt
View file @
20b14673
...
...
@@ -4,6 +4,7 @@ import chat.rocket.android.core.lifecycle.CancelStrategy
import
chat.rocket.android.infrastructure.LocalRepository
import
chat.rocket.android.server.domain.GetChatRoomsInteractor
import
chat.rocket.android.server.domain.GetCurrentServerInteractor
import
chat.rocket.android.server.domain.RefreshSettingsInteractor
import
chat.rocket.android.server.domain.SaveChatRoomsInteractor
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.android.util.extensions.launchUI
...
...
@@ -28,6 +29,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
private
val
getChatRoomsInteractor
:
GetChatRoomsInteractor
,
private
val
saveChatRoomsInteractor
:
SaveChatRoomsInteractor
,
private
val
localRepository
:
LocalRepository
,
private
val
refreshSettingsInteractor
:
RefreshSettingsInteractor
,
factory
:
RocketChatClientFactory
)
{
private
val
client
:
RocketChatClient
=
factory
.
create
(
serverInteractor
.
get
()
!!
)
private
val
currentServer
=
serverInteractor
.
get
()
!!
...
...
@@ -36,6 +38,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
private
val
stateChannel
=
Channel
<
State
>()
fun
loadChatRooms
()
{
refreshSettingsInteractor
.
refreshAsync
(
currentServer
)
launchUI
(
strategy
)
{
view
.
showLoading
()
try
{
...
...
app/src/main/java/chat/rocket/android/server/domain/RefreshSettingsInteractor.kt
0 → 100644
View file @
20b14673
package
chat.rocket.android.server.domain
import
chat.rocket.android.server.infraestructure.RocketChatClientFactory
import
chat.rocket.core.internal.rest.settings
import
kotlinx.coroutines.experimental.CommonPool
import
kotlinx.coroutines.experimental.async
import
kotlinx.coroutines.experimental.withContext
import
javax.inject.Inject
class
RefreshSettingsInteractor
@Inject
constructor
(
private
val
factory
:
RocketChatClientFactory
,
private
val
repository
:
SettingsRepository
)
{
private
var
settingsFilter
=
arrayOf
(
SITE_URL
,
SITE_NAME
,
FAVICON_512
,
USE_REALNAME
,
ALLOW_ROOM_NAME_SPECIAL_CHARS
,
FAVORITE_ROOMS
,
ACCOUNT_LOGIN_FORM
,
ACCOUNT_GOOGLE
,
ACCOUNT_FACEBOOK
,
ACCOUNT_GITHUB
,
ACCOUNT_GITLAB
,
ACCOUNT_LINKEDIN
,
ACCOUNT_METEOR
,
ACCOUNT_TWITTER
,
ACCOUNT_WORDPRESS
,
LDAP_ENABLE
,
ACCOUNT_REGISTRATION
,
UPLOAD_STORAGE_TYPE
,
UPLOAD_MAX_FILE_SIZE
,
UPLOAD_WHITELIST_MIMETYPES
,
HIDE_USER_JOIN
,
HIDE_USER_LEAVE
,
HIDE_TYPE_AU
,
HIDE_MUTE_UNMUTE
,
HIDE_TYPE_RU
,
ACCOUNT_CUSTOM_FIELDS
,
ALLOW_MESSAGE_DELETING
,
ALLOW_MESSAGE_EDITING
,
ALLOW_MESSAGE_PINNING
,
SHOW_DELETED_STATUS
,
SHOW_EDITED_STATUS
)
suspend
fun
refresh
(
server
:
String
)
{
withContext
(
CommonPool
)
{
factory
.
create
(
server
).
let
{
client
->
val
settings
=
client
.
settings
(*
settingsFilter
)
repository
.
save
(
server
,
settings
)
}
}
}
fun
refreshAsync
(
server
:
String
)
{
async
{
try
{
refresh
(
server
)
}
catch
(
ex
:
Exception
)
{
ex
.
printStackTrace
()
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/server/domain/SettingsRepository.kt
View file @
20b14673
package
chat.rocket.android.server.domain
import
chat.rocket.android.util.extensions.mapToTypedArray
import
chat.rocket.core.model.Value
typealias
PublicSettings
=
Map
<
String
,
Value
<
Any
>>
...
...
@@ -28,7 +29,9 @@ const val USE_REALNAME = "UI_Use_Real_Name"
const
val
ALLOW_ROOM_NAME_SPECIAL_CHARS
=
"UI_Allow_room_names_with_special_chars"
const
val
FAVORITE_ROOMS
=
"Favorite_Rooms"
const
val
LDAP_ENABLE
=
"LDAP_Enable"
const
val
STORAGE_TYPE
=
"FileUpload_Storage_Type"
const
val
UPLOAD_STORAGE_TYPE
=
"FileUpload_Storage_Type"
const
val
UPLOAD_MAX_FILE_SIZE
=
"FileUpload_MaxFileSize"
const
val
UPLOAD_WHITELIST_MIMETYPES
=
"FileUpload_MediaTypeWhiteList"
const
val
HIDE_USER_JOIN
=
"Message_HideType_uj"
const
val
HIDE_USER_LEAVE
=
"Message_HideType_ul"
const
val
HIDE_TYPE_AU
=
"Message_HideType_au"
...
...
@@ -66,4 +69,17 @@ fun Map<String, Value<Any>>.allowedMessageDeleting(): Boolean = this[ALLOW_MESSA
fun
Map
<
String
,
Value
<
Any
>>.
registrationEnabled
():
Boolean
{
val
value
=
this
[
ACCOUNT_REGISTRATION
]
return
value
?.
value
==
"Public"
}
fun
Map
<
String
,
Value
<
Any
>>.
uploadMimeTypeFilter
():
Array
<
String
>
{
val
values
=
this
[
UPLOAD_WHITELIST_MIMETYPES
]
?.
value
values
?.
let
{
it
as
String
}
?.
split
(
","
)
?.
let
{
return
it
.
mapToTypedArray
{
it
.
trim
()
}
}
return
arrayOf
(
"*/*"
)
}
fun
Map
<
String
,
Value
<
Any
>>.
uploadMaxFileSize
():
Int
{
return
this
[
UPLOAD_MAX_FILE_SIZE
]
?.
value
?.
let
{
it
as
Int
}
?:
Int
.
MAX_VALUE
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Collections.kt
0 → 100644
View file @
20b14673
package
chat.rocket.android.util.extensions
inline
fun
<
T
,
reified
R
>
List
<
T
>.
mapToTypedArray
(
transform
:
(
T
)
->
R
):
Array
<
R
>
{
return
when
(
this
)
{
is
RandomAccess
->
Array
(
size
)
{
index
->
transform
(
this
[
index
])
}
else
->
with
(
iterator
())
{
Array
(
size
)
{
transform
(
next
())
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Text.kt
View file @
20b14673
package
chat.rocket.android.util.extensions
import
android.content.ContentResolver
import
android.content.Context
import
android.net.Uri
import
android.widget.TextView
import
android.provider.OpenableColumns
import
android.webkit.MimeTypeMap
import
android.provider.MediaStore
import
ru.noties.markwon.Markwon
fun
String
.
ifEmpty
(
value
:
String
):
String
{
...
...
@@ -43,50 +37,4 @@ var TextView.content: CharSequence
text
=
value
Markwon
.
scheduleDrawables
(
this
)
Markwon
.
scheduleTableRows
(
this
)
}
fun
Uri
.
getFileName
(
context
:
Context
):
String
?
{
val
cursor
=
context
.
contentResolver
.
query
(
this
,
null
,
null
,
null
,
null
,
null
)
var
fileName
:
String
?
=
null
cursor
.
use
{
cursor
->
if
(
cursor
!=
null
&&
cursor
.
moveToFirst
())
{
fileName
=
cursor
.
getString
(
cursor
.
getColumnIndex
(
OpenableColumns
.
DISPLAY_NAME
))
}
}
return
fileName
}
fun
Uri
.
getFileSize
(
context
:
Context
):
String
?
{
val
cursor
=
context
.
contentResolver
.
query
(
this
,
null
,
null
,
null
,
null
,
null
)
var
fileSize
:
String
?
=
null
cursor
.
use
{
cursor
->
val
sizeIndex
=
cursor
.
getColumnIndex
(
OpenableColumns
.
SIZE
)
if
(
cursor
!=
null
&&
cursor
.
moveToFirst
())
{
if
(!
cursor
.
isNull
(
sizeIndex
))
{
fileSize
=
cursor
.
getString
(
sizeIndex
)
}
}
}
return
fileSize
}
fun
Uri
.
getMimeType
(
context
:
Context
):
String
{
return
if
(
scheme
==
ContentResolver
.
SCHEME_CONTENT
)
{
context
.
contentResolver
.
getType
(
this
)
}
else
{
val
fileExtension
=
MimeTypeMap
.
getFileExtensionFromUrl
(
toString
())
MimeTypeMap
.
getSingleton
().
getMimeTypeFromExtension
(
fileExtension
.
toLowerCase
())
}
}
fun
Uri
.
getRealPathFromURI
(
context
:
Context
):
String
?
{
val
cursor
=
context
.
contentResolver
.
query
(
this
,
arrayOf
(
MediaStore
.
Images
.
Media
.
DATA
),
null
,
null
,
null
)
cursor
.
use
{
cursor
->
val
columnIndex
=
cursor
.
getColumnIndexOrThrow
(
MediaStore
.
Images
.
Media
.
DATA
)
cursor
.
moveToFirst
()
return
cursor
.
getString
(
columnIndex
)
}
}
\ No newline at end of file
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/util/extensions/Uri.kt
0 → 100644
View file @
20b14673
package
chat.rocket.android.util.extensions
import
android.annotation.TargetApi
import
android.content.ContentResolver
import
android.content.Context
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
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
{
cursor
->
if
(
cursor
!=
null
&&
cursor
.
moveToFirst
())
{
fileName
=
cursor
.
getString
(
cursor
.
getColumnIndex
(
OpenableColumns
.
DISPLAY_NAME
))
}
}
return
fileName
}
fun
Uri
.
getFileSize
(
context
:
Context
):
Int
{
val
cursor
=
context
.
contentResolver
.
query
(
this
,
null
,
null
,
null
,
null
,
null
)
var
fileSize
:
String
?
=
null
cursor
.
use
{
cursor
->
val
sizeIndex
=
cursor
.
getColumnIndex
(
OpenableColumns
.
SIZE
)
if
(
cursor
!=
null
&&
cursor
.
moveToFirst
())
{
if
(!
cursor
.
isNull
(
sizeIndex
))
{
fileSize
=
cursor
.
getString
(
sizeIndex
)
}
}
}
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
())
MimeTypeMap
.
getSingleton
().
getMimeTypeFromExtension
(
fileExtension
.
toLowerCase
())
}
}
fun
Uri
.
getRealPathFromURI
(
context
:
Context
):
String
?
{
val
cursor
=
context
.
contentResolver
.
query
(
this
,
arrayOf
(
MediaStore
.
Images
.
Media
.
DATA
),
null
,
null
,
null
)
cursor
.
use
{
cursor
->
val
columnIndex
=
cursor
.
getColumnIndexOrThrow
(
MediaStore
.
Images
.
Media
.
DATA
)
cursor
.
moveToFirst
()
return
cursor
.
getString
(
columnIndex
)
}
}
@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
if
(
cursor
.
moveToFirst
())
{
flags
=
cursor
.
getInt
(
0
)
}
cursor
.
close
()
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
)
}
\ No newline at end of file
app/src/main/res/values/strings.xml
View file @
20b14673
...
...
@@ -82,4 +82,7 @@
<!-- Pinned Messages -->
<string
name=
"title_pinned_messages"
>
Pinned Messages
</string>
<!-- Upload Messages -->
<string
name=
"max_file_size_exceeded"
>
File size %1$d exceeded max file size of %2$d bytes
</string>
</resources>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment