fix: краш «Свой звук» на FragmentActivity (0.5.5)
Ringtone picker через startActivityForResult вместо Activity Result API с большим requestCode.
This commit is contained in:
@@ -13,8 +13,8 @@ android {
|
||||
applicationId = "ru.kalinamall.seaca"
|
||||
minSdk = 26
|
||||
targetSdk = 35
|
||||
versionCode = 18
|
||||
versionName = "0.5.4"
|
||||
versionCode = 19
|
||||
versionName = "0.5.5"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
@@ -59,6 +59,7 @@ import ru.kalinamall.seaca.ui.screens.HostDetailScreen
|
||||
import ru.kalinamall.seaca.ui.screens.HostsScreen
|
||||
import ru.kalinamall.seaca.ui.screens.ProblemDetailScreen
|
||||
import ru.kalinamall.seaca.ui.screens.ProblemsScreen
|
||||
import ru.kalinamall.seaca.ui.RingtonePicker
|
||||
import ru.kalinamall.seaca.ui.screens.ReportsScreen
|
||||
import ru.kalinamall.seaca.ui.theme.SeacaTheme
|
||||
|
||||
@@ -94,6 +95,13 @@ class MainActivity : FragmentActivity() {
|
||||
deepLinkState.value = extractDeepLink(intent)
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
@Suppress("DEPRECATION")
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
RingtonePicker.handleActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
if (shouldRequireBiometric()) {
|
||||
|
||||
@@ -20,7 +20,11 @@ object NotificationSoundResolver {
|
||||
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
||||
|
||||
fun displayName(context: Context, settings: NotificationSoundSettings): String {
|
||||
val uri = resolve(context, settings)
|
||||
return RingtoneManager.getRingtone(context, uri)?.getTitle(context) ?: "—"
|
||||
return try {
|
||||
val uri = resolve(context, settings)
|
||||
RingtoneManager.getRingtone(context, uri)?.getTitle(context) ?: "—"
|
||||
} catch (_: Exception) {
|
||||
"—"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package ru.kalinamall.seaca.ui
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.media.RingtoneManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import ru.kalinamall.seaca.push.NotificationSoundResolver
|
||||
|
||||
object RingtonePicker {
|
||||
private const val REQUEST_CODE = 9001
|
||||
|
||||
private var callback: ((Uri?) -> Unit)? = null
|
||||
|
||||
fun launch(activity: FragmentActivity, currentUri: Uri, onResult: (Uri?) -> Unit) {
|
||||
callback = onResult
|
||||
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply {
|
||||
putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION)
|
||||
putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true)
|
||||
putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false)
|
||||
putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, NotificationSoundResolver.defaultNotificationUri())
|
||||
putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentUri)
|
||||
}
|
||||
try {
|
||||
@Suppress("DEPRECATION")
|
||||
activity.startActivityForResult(intent, REQUEST_CODE)
|
||||
} catch (_: ActivityNotFoundException) {
|
||||
callback = null
|
||||
throw ActivityNotFoundException()
|
||||
}
|
||||
}
|
||||
|
||||
fun handleActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode != REQUEST_CODE) return
|
||||
val onResult = callback ?: return
|
||||
callback = null
|
||||
val uri = if (resultCode == Activity.RESULT_OK) readResult(data) else null
|
||||
onResult(uri)
|
||||
}
|
||||
|
||||
private fun readResult(data: Intent?): Uri? {
|
||||
if (data == null) return null
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, Uri::class.java)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,10 @@
|
||||
package ru.kalinamall.seaca.ui.screens
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import android.media.RingtoneManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -64,6 +58,7 @@ import ru.kalinamall.seaca.data.ProblemDetail
|
||||
import ru.kalinamall.seaca.data.SacRepository
|
||||
import ru.kalinamall.seaca.push.NotificationHelper
|
||||
import ru.kalinamall.seaca.push.NotificationSoundResolver
|
||||
import ru.kalinamall.seaca.ui.RingtonePicker
|
||||
import ru.kalinamall.seaca.ui.components.BackArrowButton
|
||||
import ru.kalinamall.seaca.ui.components.ForwardArrowButton
|
||||
import ru.kalinamall.seaca.ui.util.SacDateTimes
|
||||
@@ -459,36 +454,23 @@ fun DeviceScreen(repo: SacRepository, onLogout: () -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
val ringtonePickerLauncher = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult(),
|
||||
) { result ->
|
||||
if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
|
||||
val uri = readRingtonePickerResult(result.data)
|
||||
scope.launch {
|
||||
if (uri == null) {
|
||||
repo.session.setNotificationSound(NotificationSoundSource.SYSTEM, null)
|
||||
} else {
|
||||
repo.session.setNotificationSound(NotificationSoundSource.CUSTOM, uri.toString())
|
||||
}
|
||||
applySoundChannels(repo.session.getNotificationSoundSettings())
|
||||
}
|
||||
}
|
||||
|
||||
fun openRingtonePicker() {
|
||||
if (activity == null) {
|
||||
Toast.makeText(context, "Не удалось открыть выбор звука", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
val currentUri = NotificationSoundResolver.resolve(context, latestSoundSettings)
|
||||
val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply {
|
||||
putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION)
|
||||
putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true)
|
||||
putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false)
|
||||
putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, NotificationSoundResolver.defaultNotificationUri())
|
||||
putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currentUri)
|
||||
}
|
||||
try {
|
||||
ringtonePickerLauncher.launch(intent)
|
||||
RingtonePicker.launch(activity, currentUri) { uri ->
|
||||
scope.launch {
|
||||
if (uri == null) {
|
||||
repo.session.setNotificationSound(NotificationSoundSource.SYSTEM, null)
|
||||
} else {
|
||||
repo.session.setNotificationSound(NotificationSoundSource.CUSTOM, uri.toString())
|
||||
}
|
||||
applySoundChannels(repo.session.getNotificationSoundSettings())
|
||||
}
|
||||
}
|
||||
} catch (_: ActivityNotFoundException) {
|
||||
Toast.makeText(context, "На устройстве нет выбора звука уведомлений", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
@@ -730,14 +712,4 @@ private fun Field(label: String, value: String) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun readRingtonePickerResult(data: Intent?): Uri? {
|
||||
if (data == null) return null
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, Uri::class.java)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
|
||||
}
|
||||
}
|
||||
|
||||
private fun JsonElement.toPrettyString(): String = toString()
|
||||
|
||||
Reference in New Issue
Block a user