fix: Don't crash when displaying update check dialog (#463)

Previous code injected `ApplicationContext`, which is not themed, and
caused a crash if the "update" dialog was shown.

Fix by passing the necesssary context in explicitly when the check is
performed.
This commit is contained in:
Nik Clayton 2024-02-22 14:16:05 +01:00 committed by GitHub
parent 2162e03e1f
commit 203784d718
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 9 additions and 18 deletions

View File

@ -17,21 +17,18 @@
package app.pachli.updatecheck
import android.content.Context
import android.content.Intent
import android.net.Uri
import app.pachli.BuildConfig
import app.pachli.core.preferences.SharedPreferencesRepository
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class UpdateCheck @Inject constructor(
@ApplicationContext context: Context,
sharedPreferencesRepository: SharedPreferencesRepository,
private val fdroidService: FdroidService,
) : UpdateCheckBase(context, sharedPreferencesRepository) {
) : UpdateCheckBase(sharedPreferencesRepository) {
override val updateIntent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("market://details?id=${BuildConfig.APPLICATION_ID}")
}

View File

@ -17,18 +17,15 @@
package app.pachli.updatecheck
import android.content.Context
import android.content.Intent
import android.net.Uri
import app.pachli.core.preferences.SharedPreferencesRepository
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
class UpdateCheck @Inject constructor(
@ApplicationContext context: Context,
sharedPreferencesRepository: SharedPreferencesRepository,
private val gitHubService: GitHubService,
) : UpdateCheckBase(context, sharedPreferencesRepository) {
) : UpdateCheckBase(sharedPreferencesRepository) {
private val versionCodeExtractor = """(\d+)\.apk""".toRegex()
override val updateIntent = Intent(Intent.ACTION_VIEW).apply {

View File

@ -17,21 +17,18 @@
package app.pachli.updatecheck
import android.content.Context
import android.content.Intent
import android.net.Uri
import app.pachli.BuildConfig
import app.pachli.core.preferences.SharedPreferencesRepository
import com.google.android.play.core.appupdate.AppUpdateManager
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import kotlinx.coroutines.suspendCancellableCoroutine
class UpdateCheck @Inject constructor(
@ApplicationContext context: Context,
sharedPreferencesRepository: SharedPreferencesRepository,
private val appUpdateManager: AppUpdateManager,
) : UpdateCheckBase(context, sharedPreferencesRepository) {
) : UpdateCheckBase(sharedPreferencesRepository) {
override val updateIntent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(
"https://play.google.com/store/apps/details?id=${BuildConfig.APPLICATION_ID}",

View File

@ -427,7 +427,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
showJankyAnimationWarning()
}
lifecycleScope.launch { updateCheck.checkForUpdate() }
lifecycleScope.launch { updateCheck.checkForUpdate(this@MainActivity) }
}
/** Warn the user about possibly-broken animations. */

View File

@ -352,7 +352,7 @@ class PreferencesFragment : PreferenceFragmentCompat() {
key = PrefKeys.UPDATE_NOTIFICATION_LAST_NOTIFICATION_MS
setOnPreferenceClickListener {
lifecycleScope.launch {
if (updateCheck.checkForUpdate(true) == AT_LATEST) {
if (updateCheck.checkForUpdate(this@PreferencesFragment.requireContext(), true) == AT_LATEST) {
Toast.makeText(
this@PreferencesFragment.requireContext(),
getString(R.string.pref_update_check_no_updates),

View File

@ -34,7 +34,6 @@ import app.pachli.updatecheck.UpdateCheckResult.DIALOG_SHOWN
import app.pachli.updatecheck.UpdateCheckResult.IGNORED
import app.pachli.updatecheck.UpdateCheckResult.SKIPPED_BECAUSE_NEVER
import app.pachli.updatecheck.UpdateCheckResult.SKIPPED_BECAUSE_TOO_SOON
import dagger.hilt.android.qualifiers.ApplicationContext
import java.time.Instant
import java.util.Date
import javax.inject.Singleton
@ -86,7 +85,6 @@ enum class UpdateCheckResult {
@Singleton
abstract class UpdateCheckBase(
@ApplicationContext private val context: Context,
private val sharedPreferencesRepository: SharedPreferencesRepository,
) : Preference.SummaryProvider<Preference> {
/** An intent that can be used to start the update process (e.g., open a store listing) */
@ -107,12 +105,14 @@ abstract class UpdateCheckBase(
* The user can start an update, ignore this version, or dismiss all future update
* notifications.
*
* @param context Themed context used to display the "Update" dialog. Must be from an
* activity that uses `Theme.AppCompat` or a descendent.
* @param force If true then the user's preferences for update checking frequency are
* ignored and the update check is always performed.
*
* @return The result of performing the update check
*/
suspend fun checkForUpdate(force: Boolean = false): UpdateCheckResult {
suspend fun checkForUpdate(context: Context, force: Boolean = false): UpdateCheckResult {
val frequency = UpdateNotificationFrequency.from(
sharedPreferencesRepository.getString(PrefKeys.UPDATE_NOTIFICATION_FREQUENCY, null),
)
@ -205,7 +205,7 @@ abstract class UpdateCheckBase(
val dateString = AbsoluteTimeFormatter().format(Date.from(nextCheck))
return context.getString(R.string.pref_update_next_scheduled_check, dateString)
return preference.context.getString(R.string.pref_update_next_scheduled_check, dateString)
}
companion object {