Fix crash on download update
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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?) {
|
||||||
|
|||||||
@@ -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)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user