Fix crash on download update

This commit is contained in:
Koitharu
2023-10-02 15:15:44 +03:00
parent 43075c52d1
commit 4fa1382ce9
4 changed files with 49 additions and 14 deletions

View File

@@ -83,6 +83,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
private val viewModel by viewModels<MainViewModel>() private val viewModel by viewModels<MainViewModel>()
private val searchSuggestionViewModel by viewModels<SearchSuggestionViewModel>() private val searchSuggestionViewModel by viewModels<SearchSuggestionViewModel>()
private val closeSearchCallback = CloseSearchCallback() private val closeSearchCallback = CloseSearchCallback()
private val appUpdateDialog = AppUpdateDialog(this)
private lateinit var navigationDelegate: MainNavigationDelegate private lateinit var navigationDelegate: MainNavigationDelegate
private lateinit var appUpdateBadge: OptionsMenuBadgeHelper private lateinit var appUpdateBadge: OptionsMenuBadgeHelper
@@ -198,8 +199,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
R.id.action_app_update -> { R.id.action_app_update -> {
viewModel.appUpdate.value?.also { viewModel.appUpdate.value?.also {
AppUpdateDialog(this) appUpdateDialog.show(it)
.show(it)
} != null } != null
} }

View File

@@ -29,6 +29,7 @@ import org.koitharu.kotatsu.databinding.ActivitySettingsBinding
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.settings.about.AboutSettingsFragment import org.koitharu.kotatsu.settings.about.AboutSettingsFragment
import org.koitharu.kotatsu.settings.about.AppUpdateDialog
import org.koitharu.kotatsu.settings.sources.SourceSettingsFragment import org.koitharu.kotatsu.settings.sources.SourceSettingsFragment
import org.koitharu.kotatsu.settings.sources.SourcesManageFragment import org.koitharu.kotatsu.settings.sources.SourcesManageFragment
import org.koitharu.kotatsu.settings.tracker.TrackerSettingsFragment import org.koitharu.kotatsu.settings.tracker.TrackerSettingsFragment
@@ -41,6 +42,8 @@ class SettingsActivity :
AppBarOwner, AppBarOwner,
FragmentManager.OnBackStackChangedListener { FragmentManager.OnBackStackChangedListener {
val appUpdateDialog = AppUpdateDialog(this)
override val appBar: AppBarLayout override val appBar: AppBarLayout
get() = viewBinding.appbar get() = viewBinding.appbar

View File

@@ -20,6 +20,7 @@ import org.koitharu.kotatsu.core.ui.BasePreferenceFragment
import org.koitharu.kotatsu.core.util.ShareHelper import org.koitharu.kotatsu.core.util.ShareHelper
import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.settings.SettingsActivity
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
@@ -76,7 +77,7 @@ class AboutSettingsFragment : BasePreferenceFragment(R.string.about) {
Snackbar.make(listView, R.string.no_update_available, Snackbar.LENGTH_SHORT).show() Snackbar.make(listView, R.string.no_update_available, Snackbar.LENGTH_SHORT).show()
return return
} }
AppUpdateDialog(context ?: return).show(version) (activity as SettingsActivity).appUpdateDialog.show(version)
} }
private fun openLink(url: String, title: CharSequence?) { private fun openLink(url: String, title: CharSequence?) {

View File

@@ -1,10 +1,14 @@
package org.koitharu.kotatsu.settings.about package org.koitharu.kotatsu.settings.about
import android.Manifest
import android.app.DownloadManager import android.app.DownloadManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build
import android.os.Environment import android.os.Environment
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.text.buildSpannedString import androidx.core.text.buildSpannedString
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -14,19 +18,32 @@ import org.koitharu.kotatsu.core.github.AppVersion
import org.koitharu.kotatsu.core.util.FileSize import org.koitharu.kotatsu.core.util.FileSize
import com.google.android.material.R as materialR import com.google.android.material.R as materialR
class AppUpdateDialog(private val context: Context) { class AppUpdateDialog(private val activity: AppCompatActivity) {
private lateinit var latestVersion: AppVersion
private val permissionRequest = activity.registerForActivityResult(
ActivityResultContracts.RequestPermission(),
) {
if (it) {
downloadUpdateImpl()
} else {
openInBrowser()
}
}
fun show(version: AppVersion) { fun show(version: AppVersion) {
latestVersion = version
val message = buildSpannedString { val message = buildSpannedString {
append(context.getString(R.string.new_version_s, version.name)) append(activity.getString(R.string.new_version_s, version.name))
appendLine() appendLine()
append(context.getString(R.string.size_s, FileSize.BYTES.format(context, version.apkSize))) append(activity.getString(R.string.size_s, FileSize.BYTES.format(activity, version.apkSize)))
appendLine() appendLine()
appendLine() appendLine()
append(Markwon.create(context).toMarkdown(version.description)) append(Markwon.create(activity).toMarkdown(version.description))
} }
MaterialAlertDialogBuilder( MaterialAlertDialogBuilder(
context, activity,
materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered, materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered,
) )
.setTitle(R.string.app_update_available) .setTitle(R.string.app_update_available)
@@ -34,24 +51,38 @@ class AppUpdateDialog(private val context: Context) {
.setIcon(R.drawable.ic_app_update) .setIcon(R.drawable.ic_app_update)
.setNeutralButton(R.string.open_in_browser) { _, _ -> .setNeutralButton(R.string.open_in_browser) { _, _ ->
val intent = Intent(Intent.ACTION_VIEW, version.url.toUri()) val intent = Intent(Intent.ACTION_VIEW, version.url.toUri())
context.startActivity(Intent.createChooser(intent, context.getString(R.string.open_in_browser))) activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.open_in_browser)))
}.setPositiveButton(R.string.update) { _, _ -> }.setPositiveButton(R.string.update) { _, _ ->
downloadUpdate(version) downloadUpdate()
}.setNegativeButton(android.R.string.cancel, null) }.setNegativeButton(android.R.string.cancel, null)
.setCancelable(false) .setCancelable(false)
.create() .create()
.show() .show()
} }
private fun downloadUpdate(version: AppVersion) { private fun downloadUpdate() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
permissionRequest.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
} else {
downloadUpdateImpl()
}
}
private fun downloadUpdateImpl() {
val version = latestVersion
val url = version.apkUrl.toUri() val url = version.apkUrl.toUri()
val dm = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager val dm = activity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val request = DownloadManager.Request(url) val request = DownloadManager.Request(url)
.setTitle("${context.getString(R.string.app_name)} v${version.name}") .setTitle("${activity.getString(R.string.app_name)} v${version.name}")
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, url.lastPathSegment) .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, url.lastPathSegment)
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setMimeType("application/vnd.android.package-archive") .setMimeType("application/vnd.android.package-archive")
dm.enqueue(request) dm.enqueue(request)
Toast.makeText(context, R.string.download_started, Toast.LENGTH_SHORT).show() Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show()
}
private fun openInBrowser() {
val intent = Intent(Intent.ACTION_VIEW, latestVersion.url.toUri())
activity.startActivity(Intent.createChooser(intent, activity.getString(R.string.open_in_browser)))
} }
} }