diff --git a/app/src/main/java/sushi/hardcore/aira/ChatActivity.kt b/app/src/main/java/sushi/hardcore/aira/ChatActivity.kt index c9c6e83..dfe6117 100644 --- a/app/src/main/java/sushi/hardcore/aira/ChatActivity.kt +++ b/app/src/main/java/sushi/hardcore/aira/ChatActivity.kt @@ -311,7 +311,10 @@ class ChatActivity : ServiceBoundActivity() { } private fun scrollToBottom() { - binding.recyclerChat.smoothScrollToPosition(chatAdapter.itemCount-1) + val target = chatAdapter.itemCount-1 + if (target >= 0) { + binding.recyclerChat.smoothScrollToPosition(target) + } } override fun onCreateOptionsMenu(menu: Menu): Boolean { diff --git a/app/src/main/java/sushi/hardcore/aira/MainActivity.kt b/app/src/main/java/sushi/hardcore/aira/MainActivity.kt index bccb3d1..69512d5 100644 --- a/app/src/main/java/sushi/hardcore/aira/MainActivity.kt +++ b/app/src/main/java/sushi/hardcore/aira/MainActivity.kt @@ -8,7 +8,6 @@ import android.os.Bundle import android.os.IBinder import android.view.Menu import android.view.MenuItem -import android.view.View import android.widget.AbsListView import android.widget.AdapterView import android.widget.Toast @@ -117,33 +116,28 @@ class MainActivity : ServiceBoundActivity() { } setOnScrollListener(onSessionsScrollListener) } - if (openedToShareFile) { - binding.offlineSessions.visibility = View.GONE - binding.textOfflineSessions.visibility = View.GONE - } else { - offlineSessionAdapter = SessionAdapter(this) - binding.offlineSessions.apply { - adapter = offlineSessionAdapter - onItemClickListener = if (openedToShareFile) { - onSessionsItemClickSendFile - } else { - AdapterView.OnItemClickListener { _, _, position, _ -> - if (isSelecting()) { - changeSelection(offlineSessionAdapter!!, position) - } else { - launchChatActivity(offlineSessionAdapter!!.getItem(position)) - } + offlineSessionAdapter = SessionAdapter(this) + binding.offlineSessions.apply { + adapter = offlineSessionAdapter + onItemClickListener = if (openedToShareFile) { + onSessionsItemClickSendFile + } else { + AdapterView.OnItemClickListener { _, _, position, _ -> + if (isSelecting()) { + changeSelection(offlineSessionAdapter!!, position) + } else { + launchChatActivity(offlineSessionAdapter!!.getItem(position)) } } - onItemLongClickListener = AdapterView.OnItemLongClickListener { _, _, position, _ -> - changeSelection(offlineSessionAdapter!!, position) - true - } - setOnScrollListener(onSessionsScrollListener) } - if (intent.action == NotificationBroadcastReceiver.ACTION_LOGOUT) { - askLogOut() + onItemLongClickListener = AdapterView.OnItemLongClickListener { _, _, position, _ -> + changeSelection(offlineSessionAdapter!!, position) + true } + setOnScrollListener(onSessionsScrollListener) + } + if (intent.action == NotificationBroadcastReceiver.ACTION_LOGOUT) { + askLogOut() } serviceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder) { @@ -347,13 +341,15 @@ class MainActivity : ServiceBoundActivity() { Toast.makeText(this, R.string.open_uri_failed, Toast.LENGTH_SHORT).show() } else { val msg = if (uris!!.size == 1) { - val sendFile = FileUtils.openFileFromUri(this, uris!![0]) - if (sendFile == null) { - Toast.makeText(this, R.string.open_uri_failed, Toast.LENGTH_SHORT).show() + val result = FileUtils.openFileFromUri(this, uris!![0]) + if (result.file == null) { + if (!result.errorHandled) { + Toast.makeText(this, R.string.open_uri_failed, Toast.LENGTH_SHORT).show() + } return } else { - sendFile.inputStream.close() - getString(R.string.ask_send_single_file, sendFile.fileName, FileUtils.formatSize(sendFile.fileSize), session.name ?: session.ip) + result.file.inputStream.close() + getString(R.string.ask_send_single_file, result.file.fileName, FileUtils.formatSize(result.file.fileSize), session.name ?: session.ip) } } else { getString(R.string.ask_send_multiple_files, uris!!.size, session.name ?: session.ip) diff --git a/app/src/main/java/sushi/hardcore/aira/background_service/AIRAService.kt b/app/src/main/java/sushi/hardcore/aira/background_service/AIRAService.kt index af9293b..a734a10 100644 --- a/app/src/main/java/sushi/hardcore/aira/background_service/AIRAService.kt +++ b/app/src/main/java/sushi/hardcore/aira/background_service/AIRAService.kt @@ -159,7 +159,7 @@ class AIRAService : Service() { val files = mutableListOf() var useLargeFileTransfer = false for (uri in uris) { - FileUtils.openFileFromUri(this, uri)?.let { sendFile -> + FileUtils.openFileFromUri(this, uri).file?.let { sendFile -> files.add(sendFile) if (sendFile.fileSize > Constants.fileSizeLimit) { useLargeFileTransfer = true diff --git a/app/src/main/java/sushi/hardcore/aira/utils/FileUtils.kt b/app/src/main/java/sushi/hardcore/aira/utils/FileUtils.kt index cffca60..daf2cee 100644 --- a/app/src/main/java/sushi/hardcore/aira/utils/FileUtils.kt +++ b/app/src/main/java/sushi/hardcore/aira/utils/FileUtils.kt @@ -2,6 +2,7 @@ package sushi.hardcore.aira.utils import android.content.ContentValues import android.content.Context +import android.content.Intent import android.net.Uri import android.os.Environment import android.provider.MediaStore @@ -15,8 +16,8 @@ import java.io.OutputStream import java.text.DecimalFormat import java.text.SimpleDateFormat import java.util.* -import kotlin.math.pow import kotlin.math.log10 +import kotlin.math.pow object FileUtils { private val units = arrayOf("B", "kB", "MB", "GB", "TB") @@ -29,8 +30,16 @@ object FileUtils { ) + " " + units[digitGroups] } - fun openFileFromUri(context: Context, uri: Uri): SendFile? { + class SendFileResult(val file: SendFile? = null, val errorHandled: Boolean = false) + + fun openFileFromUri(context: Context, uri: Uri): SendFileResult { var sendFile: SendFile? = null + try { + context.grantUriPermission(context.packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION) + } catch (e: SecurityException) { + Toast.makeText(context, e.localizedMessage, Toast.LENGTH_LONG).show() + return SendFileResult(sendFile, true) + } val cursor = context.contentResolver.query(uri, null, null, null, null) if (cursor != null) { if (cursor.moveToFirst()) { @@ -46,7 +55,7 @@ object FileUtils { } cursor.close() } - return sendFile + return SendFileResult(sendFile) } class DownloadFile(val fileName: String, val outputStream: OutputStream?)