Trying to prevent crashes seen on Crashlytics

This commit is contained in:
Sylvain Berfini 2022-04-29 14:02:32 +02:00
parent 5891babc5c
commit 2e8d061e22
7 changed files with 31 additions and 12 deletions

View file

@ -76,6 +76,8 @@ class RemoteProvisioningFragment : GenericFragment<AssistantRemoteProvisioningFr
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
sharedViewModel.remoteProvisioningUrl.value = null if (this::sharedViewModel.isInitialized) {
sharedViewModel.remoteProvisioningUrl.value = null
}
} }
} }

View file

@ -89,12 +89,15 @@ class ContactEditorViewModel(val c: Friend?) : ViewModel(), ContactDataInterface
if (contact == null) { if (contact == null) {
created = true created = true
val nativeId = if (PermissionHelper.get().hasWriteContactsPermission()) { // From Crashlytics it seems both permissions are required...
val nativeId = if (PermissionHelper.get().hasReadContactsPermission() &&
PermissionHelper.get().hasWriteContactsPermission()
) {
Log.i("[Contact Editor] Creating native contact") Log.i("[Contact Editor] Creating native contact")
NativeContactEditor.createAndroidContact(syncAccountName, syncAccountType) NativeContactEditor.createAndroidContact(syncAccountName, syncAccountType)
.toString() .toString()
} else { } else {
Log.e("[Contact Editor] Can't native contact, permission denied") Log.e("[Contact Editor] Can't create native contact, permission denied")
null null
} }
contact = coreContext.core.createFriend() contact = coreContext.core.createFriend()

View file

@ -349,9 +349,14 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
viewModel.showOkButton( viewModel.showOkButton(
{ {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) try {
startActivity(browserIntent) val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
dialog.dismiss() startActivity(browserIntent)
} catch (ise: IllegalStateException) {
Log.e("[Dialer] Can't start ACTION_VIEW intent, IllegalStateException: $ise")
} finally {
dialog.dismiss()
}
}, },
getString(R.string.dialog_ok) getString(R.string.dialog_ok)
) )

View file

@ -51,7 +51,10 @@ class ContactAvatarView : LinearLayout {
) )
} }
fun setData(data: ContactDataInterface) { fun setData(data: ContactDataInterface?) {
// From Crashlytics it seems this function can be called with null parameter...
data ?: return
val contact = data.contact.value val contact = data.contact.value
val initials = if (contact != null) { val initials = if (contact != null) {
AppUtils.getInitials(contact.name ?: "") AppUtils.getInitials(contact.name ?: "")

View file

@ -93,7 +93,8 @@ class ContactLoader : LoaderManager.LoaderCallbacks<Cursor> {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
try { try {
while (!cursor.isClosed && cursor.moveToNext()) { // Cursor can be null now that we are on a different dispatcher according to Crashlytics
while (cursor != null && !cursor.isClosed && cursor.moveToNext()) {
try { try {
val id: String = val id: String =
cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Data.CONTACT_ID)) cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Data.CONTACT_ID))
@ -224,6 +225,8 @@ class ContactLoader : LoaderManager.LoaderCallbacks<Cursor> {
Log.e("[Contacts Loader] State Data Exception: $sde") Log.e("[Contacts Loader] State Data Exception: $sde")
} catch (ise: IllegalStateException) { } catch (ise: IllegalStateException) {
Log.e("[Contacts Loader] Illegal State Exception: $ise") Log.e("[Contacts Loader] Illegal State Exception: $ise")
} catch (e: Exception) {
Log.e("[Contacts Loader] Exception: $e")
} finally { } finally {
cancel() cancel()
} }

View file

@ -203,14 +203,15 @@ fun setEditTextOnFocusChangeVisibilityOf(editText: EditText, view: View) {
} }
@BindingAdapter("selectedIndex", "settingListener") @BindingAdapter("selectedIndex", "settingListener")
fun spinnerSetting(spinner: Spinner, selectedIndex: Int, listener: SettingListener) { fun spinnerSetting(spinner: Spinner, selectedIndex: Int, listener: SettingListener?) {
spinner.setSelection(selectedIndex, true) spinner.setSelection(selectedIndex, true)
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {} override fun onNothingSelected(parent: AdapterView<*>?) {}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
listener.onListValueChanged(position) // From Crashlytics it seems this method may be called with a null listener
listener?.onListValueChanged(position)
} }
} }
} }

View file

@ -47,11 +47,13 @@ class LinphoneUtils {
account.params.identityAddress?.asStringUriOnly() == address.asStringUriOnly() account.params.identityAddress?.asStringUriOnly() == address.asStringUriOnly()
} }
val localDisplayName = account?.params?.identityAddress?.displayName val localDisplayName = account?.params?.identityAddress?.displayName
if (localDisplayName != null) { // Do not return an empty local display name
if (localDisplayName != null && localDisplayName.isNotEmpty()) {
return localDisplayName return localDisplayName
} }
} }
return address.displayName ?: address.username ?: "" // Do not return an empty display name
return address.displayName ?: address.username ?: address.asString()
} }
fun getDisplayableAddress(address: Address?): String { fun getDisplayableAddress(address: Address?): String {