mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Prevent crashes due to various exceptions + fixed navigation issue
This commit is contained in:
parent
87adf9867e
commit
cd1dbc7a08
6 changed files with 131 additions and 91 deletions
|
|
@ -24,6 +24,7 @@ import android.content.Context.CLIPBOARD_SERVICE
|
|||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.GenericFragment
|
||||
|
|
@ -73,12 +74,16 @@ class PhoneAccountValidationFragment : GenericFragment<AssistantPhoneAccountVali
|
|||
}
|
||||
}
|
||||
viewModel.isLinking.value == true -> {
|
||||
val args = Bundle()
|
||||
args.putString(
|
||||
"Identity",
|
||||
"sip:${viewModel.accountCreator.username}@${viewModel.accountCreator.domain}"
|
||||
)
|
||||
navigateToAccountSettings(args)
|
||||
if (findNavController().graph.id == R.id.settings_nav_graph_xml) {
|
||||
val args = Bundle()
|
||||
args.putString(
|
||||
"Identity",
|
||||
"sip:${viewModel.accountCreator.username}@${viewModel.accountCreator.domain}"
|
||||
)
|
||||
navigateToAccountSettings(args)
|
||||
} else {
|
||||
requireActivity().finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import org.linphone.activities.assistant.viewmodels.WelcomeViewModel
|
|||
import org.linphone.activities.navigateToAccountLogin
|
||||
import org.linphone.activities.navigateToEmailAccountCreation
|
||||
import org.linphone.activities.navigateToRemoteProvisioning
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.AssistantWelcomeFragmentBinding
|
||||
|
||||
class WelcomeFragment : GenericFragment<AssistantWelcomeFragmentBinding>() {
|
||||
|
|
@ -99,7 +100,11 @@ class WelcomeFragment : GenericFragment<AssistantWelcomeFragmentBinding>() {
|
|||
Intent.ACTION_VIEW,
|
||||
Uri.parse(getString(R.string.assistant_general_terms_link))
|
||||
)
|
||||
startActivity(browserIntent)
|
||||
try {
|
||||
startActivity(browserIntent)
|
||||
} catch (e: Exception) {
|
||||
Log.e("[Welcome] Can't start activity: $e")
|
||||
}
|
||||
}
|
||||
}
|
||||
spannable.setSpan(clickableSpan, termsMatcher.start(0), termsMatcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
|
|
@ -113,7 +118,11 @@ class WelcomeFragment : GenericFragment<AssistantWelcomeFragmentBinding>() {
|
|||
Intent.ACTION_VIEW,
|
||||
Uri.parse(getString(R.string.assistant_privacy_policy_link))
|
||||
)
|
||||
startActivity(browserIntent)
|
||||
try {
|
||||
startActivity(browserIntent)
|
||||
} catch (e: Exception) {
|
||||
Log.e("[Welcome] Can't start activity: $e")
|
||||
}
|
||||
}
|
||||
}
|
||||
spannable.setSpan(clickableSpan, policyMatcher.start(0), policyMatcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
|||
if (!File(path).exists()) {
|
||||
(requireActivity() as MainActivity).showSnackBar(R.string.chat_room_file_not_found)
|
||||
} else {
|
||||
Log.i("[Chat Message] Opening file: $path")
|
||||
Log.i("[Chat Room] Opening file: $path")
|
||||
sharedViewModel.contentToOpen.value = content
|
||||
|
||||
if (corePreferences.useInAppFileViewerForNonEncryptedFiles || content.isFileEncrypted) {
|
||||
|
|
@ -456,7 +456,7 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
|||
)
|
||||
else -> {
|
||||
if (content.isFileEncrypted) {
|
||||
Log.w("[Chat Message] File is encrypted and can't be opened in one of our viewers...")
|
||||
Log.w("[Chat Room] File is encrypted and can't be opened in one of our viewers...")
|
||||
showDialogForUserConsentBeforeExportingFileInThirdPartyApp(
|
||||
content
|
||||
)
|
||||
|
|
@ -606,11 +606,11 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
|||
viewLifecycleOwner
|
||||
) {
|
||||
it.consume { uri ->
|
||||
Log.i("[Chat] Found rich content URI: $uri")
|
||||
Log.i("[Chat Room] Found rich content URI: $uri")
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.Main) {
|
||||
val path = FileUtils.getFilePath(requireContext(), uri)
|
||||
Log.i("[Chat] Rich content URI: $uri matching path is: $path")
|
||||
Log.i("[Chat Room] Rich content URI: $uri matching path is: $path")
|
||||
if (path != null) {
|
||||
chatSendingViewModel.addAttachment(path)
|
||||
}
|
||||
|
|
@ -939,18 +939,22 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
|||
val tempFileName = System.currentTimeMillis().toString() + ".jpeg"
|
||||
val file = FileUtils.getFileStoragePath(tempFileName)
|
||||
chatSendingViewModel.temporaryFileUploadPath = file
|
||||
val publicUri = FileProvider.getUriForFile(
|
||||
requireContext(),
|
||||
requireContext().getString(R.string.file_provider),
|
||||
file
|
||||
)
|
||||
capturePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, publicUri)
|
||||
capturePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
capturePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
intentsList.add(capturePictureIntent)
|
||||
try {
|
||||
val publicUri = FileProvider.getUriForFile(
|
||||
requireContext(),
|
||||
requireContext().getString(R.string.file_provider),
|
||||
file
|
||||
)
|
||||
capturePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, publicUri)
|
||||
capturePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
capturePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
intentsList.add(capturePictureIntent)
|
||||
|
||||
val captureVideoIntent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
|
||||
intentsList.add(captureVideoIntent)
|
||||
val captureVideoIntent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
|
||||
intentsList.add(captureVideoIntent)
|
||||
} catch (e: Exception) {
|
||||
Log.e("[Chat Room] Failed to pick file: $e")
|
||||
}
|
||||
}
|
||||
|
||||
val chooserIntent =
|
||||
|
|
@ -995,10 +999,10 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
|||
lifecycleScope.launch {
|
||||
Log.w("[Chat Room] Content is encrypted, requesting plain file path")
|
||||
val plainFilePath = content.plainFilePath
|
||||
Log.i("[Cht Room] Making a copy of [$plainFilePath] to the cache directory before exporting it")
|
||||
Log.i("[Chat Room] Making a copy of [$plainFilePath] to the cache directory before exporting it")
|
||||
val cacheCopyPath = FileUtils.copyFileToCache(plainFilePath)
|
||||
if (cacheCopyPath != null) {
|
||||
Log.i("[Cht Room] Cache copy has been made: $cacheCopyPath")
|
||||
Log.i("[Chat Room] Cache copy has been made: $cacheCopyPath")
|
||||
FileUtils.deleteFile(plainFilePath)
|
||||
if (!FileUtils.openFileInThirdPartyApp(requireActivity(), cacheCopyPath)) {
|
||||
showDialogToSuggestOpeningFileAsText()
|
||||
|
|
|
|||
|
|
@ -175,34 +175,45 @@ class MasterChatRoomsFragment : MasterFragment<ChatRoomMasterFragmentBinding, Ch
|
|||
)
|
||||
val swipeListener = object : RecyclerViewSwipeListener {
|
||||
override fun onLeftToRightSwipe(viewHolder: RecyclerView.ViewHolder) {
|
||||
val chatRoomViewModel = adapter.currentList[viewHolder.bindingAdapterPosition]
|
||||
chatRoomViewModel.chatRoom.markAsRead()
|
||||
adapter.notifyItemChanged(viewHolder.bindingAdapterPosition)
|
||||
val index = viewHolder.bindingAdapterPosition
|
||||
if (index < 0 || index >= adapter.currentList.size) {
|
||||
Log.e("[Chat] Index is out of bound, can't mark chat room as read")
|
||||
} else {
|
||||
val chatRoomViewModel = adapter.currentList[index]
|
||||
chatRoomViewModel.chatRoom.markAsRead()
|
||||
adapter.notifyItemChanged(index)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRightToLeftSwipe(viewHolder: RecyclerView.ViewHolder) {
|
||||
val viewModel = DialogViewModel(getString(R.string.chat_room_delete_one_dialog))
|
||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||
|
||||
viewModel.showCancelButton {
|
||||
adapter.notifyItemChanged(viewHolder.bindingAdapterPosition)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
viewModel.showDeleteButton(
|
||||
{
|
||||
val deletedChatRoom = adapter.currentList[viewHolder.bindingAdapterPosition].chatRoom
|
||||
listViewModel.deleteChatRoom(deletedChatRoom)
|
||||
if (!binding.slidingPane.isSlideable &&
|
||||
deletedChatRoom == sharedViewModel.selectedChatRoom.value
|
||||
) {
|
||||
Log.i("[Chat] Currently displayed chat room has been deleted, removing detail fragment")
|
||||
clearDisplayedChatRoom()
|
||||
}
|
||||
val index = viewHolder.bindingAdapterPosition
|
||||
if (index < 0 || index >= adapter.currentList.size) {
|
||||
Log.e("[Chat] Index is out of bound, can't delete chat room")
|
||||
} else {
|
||||
viewModel.showCancelButton {
|
||||
adapter.notifyItemChanged(index)
|
||||
dialog.dismiss()
|
||||
},
|
||||
getString(R.string.dialog_delete)
|
||||
)
|
||||
}
|
||||
|
||||
viewModel.showDeleteButton(
|
||||
{
|
||||
val deletedChatRoom =
|
||||
adapter.currentList[index].chatRoom
|
||||
listViewModel.deleteChatRoom(deletedChatRoom)
|
||||
if (!binding.slidingPane.isSlideable &&
|
||||
deletedChatRoom == sharedViewModel.selectedChatRoom.value
|
||||
) {
|
||||
Log.i("[Chat] Currently displayed chat room has been deleted, removing detail fragment")
|
||||
clearDisplayedChatRoom()
|
||||
}
|
||||
dialog.dismiss()
|
||||
},
|
||||
getString(R.string.dialog_delete)
|
||||
)
|
||||
}
|
||||
|
||||
dialog.show()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,35 +174,41 @@ class MasterContactsFragment : MasterFragment<ContactMasterFragmentBinding, Cont
|
|||
val viewModel = DialogViewModel(getString(R.string.contact_delete_one_dialog))
|
||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||
|
||||
val contactViewModel = adapter.currentList[viewHolder.bindingAdapterPosition]
|
||||
if (contactViewModel.isNativeContact.value == false) {
|
||||
adapter.notifyItemChanged(viewHolder.bindingAdapterPosition)
|
||||
val activity = requireActivity() as MainActivity
|
||||
activity.showSnackBar(R.string.contact_cant_be_deleted)
|
||||
return
|
||||
}
|
||||
val index = viewHolder.bindingAdapterPosition
|
||||
if (index < 0 || index >= adapter.currentList.size) {
|
||||
Log.e("[Contacts] Index is out of bound, can't delete contact")
|
||||
} else {
|
||||
val contactViewModel = adapter.currentList[index]
|
||||
if (contactViewModel.isNativeContact.value == false) {
|
||||
adapter.notifyItemChanged(index)
|
||||
val activity = requireActivity() as MainActivity
|
||||
activity.showSnackBar(R.string.contact_cant_be_deleted)
|
||||
return
|
||||
}
|
||||
|
||||
viewModel.showCancelButton {
|
||||
adapter.notifyItemChanged(viewHolder.bindingAdapterPosition)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
viewModel.showDeleteButton(
|
||||
{
|
||||
val deletedContact = adapter.currentList[viewHolder.bindingAdapterPosition].contact.value
|
||||
if (deletedContact != null) {
|
||||
listViewModel.deleteContact(deletedContact)
|
||||
if (!binding.slidingPane.isSlideable &&
|
||||
deletedContact == sharedViewModel.selectedContact.value
|
||||
) {
|
||||
Log.i("[Contacts] Currently displayed contact has been deleted, removing detail fragment")
|
||||
clearDisplayedContact()
|
||||
}
|
||||
}
|
||||
viewModel.showCancelButton {
|
||||
adapter.notifyItemChanged(index)
|
||||
dialog.dismiss()
|
||||
},
|
||||
getString(R.string.dialog_delete)
|
||||
)
|
||||
}
|
||||
|
||||
viewModel.showDeleteButton(
|
||||
{
|
||||
val deletedContact =
|
||||
adapter.currentList[index].contact.value
|
||||
if (deletedContact != null) {
|
||||
listViewModel.deleteContact(deletedContact)
|
||||
if (!binding.slidingPane.isSlideable &&
|
||||
deletedContact == sharedViewModel.selectedContact.value
|
||||
) {
|
||||
Log.i("[Contacts] Currently displayed contact has been deleted, removing detail fragment")
|
||||
clearDisplayedContact()
|
||||
}
|
||||
}
|
||||
dialog.dismiss()
|
||||
},
|
||||
getString(R.string.dialog_delete)
|
||||
)
|
||||
}
|
||||
|
||||
dialog.show()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,25 +158,30 @@ class MasterCallLogsFragment : MasterFragment<HistoryMasterFragmentBinding, Call
|
|||
val viewModel = DialogViewModel(getString(R.string.history_delete_one_dialog))
|
||||
val dialog: Dialog = DialogUtils.getDialog(requireContext(), viewModel)
|
||||
|
||||
viewModel.showCancelButton {
|
||||
adapter.notifyItemChanged(viewHolder.bindingAdapterPosition)
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
viewModel.showDeleteButton(
|
||||
{
|
||||
val deletedCallGroup = adapter.currentList[viewHolder.bindingAdapterPosition]
|
||||
listViewModel.deleteCallLogGroup(deletedCallGroup)
|
||||
if (!binding.slidingPane.isSlideable &&
|
||||
deletedCallGroup.lastCallLog.callId == sharedViewModel.selectedCallLogGroup.value?.lastCallLog?.callId
|
||||
) {
|
||||
Log.i("[History] Currently displayed history has been deleted, removing detail fragment")
|
||||
clearDisplayedCallHistory()
|
||||
}
|
||||
val index = viewHolder.bindingAdapterPosition
|
||||
if (index < 0 || index >= adapter.currentList.size) {
|
||||
Log.e("[History] Index is out of bound, can't delete call log")
|
||||
} else {
|
||||
viewModel.showCancelButton {
|
||||
adapter.notifyItemChanged(index)
|
||||
dialog.dismiss()
|
||||
},
|
||||
getString(R.string.dialog_delete)
|
||||
)
|
||||
}
|
||||
|
||||
viewModel.showDeleteButton(
|
||||
{
|
||||
val deletedCallGroup = adapter.currentList[index]
|
||||
listViewModel.deleteCallLogGroup(deletedCallGroup)
|
||||
if (!binding.slidingPane.isSlideable &&
|
||||
deletedCallGroup.lastCallLog.callId == sharedViewModel.selectedCallLogGroup.value?.lastCallLog?.callId
|
||||
) {
|
||||
Log.i("[History] Currently displayed history has been deleted, removing detail fragment")
|
||||
clearDisplayedCallHistory()
|
||||
}
|
||||
dialog.dismiss()
|
||||
},
|
||||
getString(R.string.dialog_delete)
|
||||
)
|
||||
}
|
||||
|
||||
dialog.show()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue