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"
|
applicationId = "ru.kalinamall.seaca"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 18
|
versionCode = 19
|
||||||
versionName = "0.5.4"
|
versionName = "0.5.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
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.HostsScreen
|
||||||
import ru.kalinamall.seaca.ui.screens.ProblemDetailScreen
|
import ru.kalinamall.seaca.ui.screens.ProblemDetailScreen
|
||||||
import ru.kalinamall.seaca.ui.screens.ProblemsScreen
|
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.screens.ReportsScreen
|
||||||
import ru.kalinamall.seaca.ui.theme.SeacaTheme
|
import ru.kalinamall.seaca.ui.theme.SeacaTheme
|
||||||
|
|
||||||
@@ -94,6 +95,13 @@ class MainActivity : FragmentActivity() {
|
|||||||
deepLinkState.value = extractDeepLink(intent)
|
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() {
|
override fun onStop() {
|
||||||
super.onStop()
|
super.onStop()
|
||||||
if (shouldRequireBiometric()) {
|
if (shouldRequireBiometric()) {
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ object NotificationSoundResolver {
|
|||||||
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
||||||
|
|
||||||
fun displayName(context: Context, settings: NotificationSoundSettings): String {
|
fun displayName(context: Context, settings: NotificationSoundSettings): String {
|
||||||
val uri = resolve(context, settings)
|
return try {
|
||||||
return RingtoneManager.getRingtone(context, uri)?.getTitle(context) ?: "—"
|
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
|
package ru.kalinamall.seaca.ui.screens
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Intent
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.runtime.rememberUpdatedState
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import android.media.RingtoneManager
|
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.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
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.data.SacRepository
|
||||||
import ru.kalinamall.seaca.push.NotificationHelper
|
import ru.kalinamall.seaca.push.NotificationHelper
|
||||||
import ru.kalinamall.seaca.push.NotificationSoundResolver
|
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.BackArrowButton
|
||||||
import ru.kalinamall.seaca.ui.components.ForwardArrowButton
|
import ru.kalinamall.seaca.ui.components.ForwardArrowButton
|
||||||
import ru.kalinamall.seaca.ui.util.SacDateTimes
|
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() {
|
fun openRingtonePicker() {
|
||||||
if (activity == null) {
|
if (activity == null) {
|
||||||
Toast.makeText(context, "Не удалось открыть выбор звука", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "Не удалось открыть выбор звука", Toast.LENGTH_SHORT).show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val currentUri = NotificationSoundResolver.resolve(context, latestSoundSettings)
|
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 {
|
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) {
|
} catch (_: ActivityNotFoundException) {
|
||||||
Toast.makeText(context, "На устройстве нет выбора звука уведомлений", Toast.LENGTH_LONG).show()
|
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()
|
private fun JsonElement.toPrettyString(): String = toString()
|
||||||
|
|||||||
Reference in New Issue
Block a user