mirror of
https://github.com/Aviortheking/Neo-Store.git
synced 2025-04-23 19:32:16 +00:00
Remove: AppDetailFragment
This commit is contained in:
parent
1477fba932
commit
c1e3d857f3
@ -1,604 +0,0 @@
|
||||
package com.looker.droidify.ui.fragments
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.looker.droidify.R
|
||||
import com.looker.droidify.content.ProductPreferences
|
||||
import com.looker.droidify.database.entity.Product
|
||||
import com.looker.droidify.database.entity.Release
|
||||
import com.looker.droidify.database.entity.Repository
|
||||
import com.looker.droidify.entity.ProductPreference
|
||||
import com.looker.droidify.entity.Screenshot
|
||||
import com.looker.droidify.installer.AppInstaller
|
||||
import com.looker.droidify.screen.MessageDialog
|
||||
import com.looker.droidify.screen.ScreenFragment
|
||||
import com.looker.droidify.screen.ScreenshotsFragment
|
||||
import com.looker.droidify.service.Connection
|
||||
import com.looker.droidify.service.DownloadService
|
||||
import com.looker.droidify.ui.activities.MainActivityX
|
||||
import com.looker.droidify.ui.adapters.AppDetailAdapter
|
||||
import com.looker.droidify.utility.RxUtils
|
||||
import com.looker.droidify.utility.Utils
|
||||
import com.looker.droidify.utility.Utils.rootInstallerEnabled
|
||||
import com.looker.droidify.utility.Utils.startUpdate
|
||||
import com.looker.droidify.utility.extension.android.Android
|
||||
import com.looker.droidify.utility.extension.text.trimAfter
|
||||
import com.looker.droidify.utility.findSuggestedProduct
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class AppDetailFragment() : ScreenFragment(), AppDetailAdapter.Callbacks {
|
||||
private val screenActivity: MainActivityX
|
||||
get() = requireActivity() as MainActivityX
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_PACKAGE_NAME = "packageName"
|
||||
private const val STATE_LAYOUT_MANAGER = "layoutManager"
|
||||
private const val STATE_ADAPTER = "adapter"
|
||||
}
|
||||
|
||||
constructor(packageName: String) : this() {
|
||||
arguments = Bundle().apply {
|
||||
putString(EXTRA_PACKAGE_NAME, packageName)
|
||||
}
|
||||
}
|
||||
|
||||
private class Nullable<T>(val value: T?)
|
||||
|
||||
private enum class Action(
|
||||
val id: Int,
|
||||
val adapterAction: AppDetailAdapter.Action,
|
||||
) {
|
||||
INSTALL(1, AppDetailAdapter.Action.INSTALL),
|
||||
UPDATE(2, AppDetailAdapter.Action.UPDATE),
|
||||
LAUNCH(3, AppDetailAdapter.Action.LAUNCH),
|
||||
DETAILS(4, AppDetailAdapter.Action.DETAILS),
|
||||
UNINSTALL(5, AppDetailAdapter.Action.UNINSTALL),
|
||||
SHARE(6, AppDetailAdapter.Action.SHARE)
|
||||
}
|
||||
|
||||
private class Installed(
|
||||
val data: com.looker.droidify.database.entity.Installed, val isSystem: Boolean,
|
||||
val launcherActivities: List<Pair<String, String>>,
|
||||
)
|
||||
|
||||
val packageName: String
|
||||
get() = requireArguments().getString(EXTRA_PACKAGE_NAME)!!
|
||||
|
||||
private var layoutManagerState: LinearLayoutManager.SavedState? = null
|
||||
|
||||
private var actions = Pair(emptySet<Action>(), null as Action?)
|
||||
private var products = emptyList<Pair<Product, Repository>>()
|
||||
private var installed: Installed? = null
|
||||
private var downloading = false
|
||||
|
||||
private var recyclerView: RecyclerView? = null
|
||||
|
||||
private var productDisposable: Disposable? = null
|
||||
private val downloadConnection = Connection(DownloadService::class.java, onBind = { _, binder ->
|
||||
binder.stateSubject
|
||||
.filter { it.packageName == packageName }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.onEach { updateDownloadState(it) }
|
||||
.flowOn(Dispatchers.Main)
|
||||
.launchIn(lifecycleScope)
|
||||
})
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
toolbar.menu.apply {
|
||||
for (action in Action.values()) {
|
||||
add(0, action.id, 0, action.adapterAction.titleResId)
|
||||
.setIcon(Utils.getToolbarIcon(toolbar.context, action.adapterAction.iconResId))
|
||||
.setVisible(false)
|
||||
.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS)
|
||||
.setOnMenuItemClickListener {
|
||||
onActionClick(action.adapterAction)
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val content = fragmentBinding.fragmentContent
|
||||
content.addView(RecyclerView(content.context).apply {
|
||||
id = android.R.id.list
|
||||
this.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
isMotionEventSplittingEnabled = false
|
||||
isVerticalScrollBarEnabled = false
|
||||
val adapter = AppDetailAdapter(this@AppDetailFragment)
|
||||
this.adapter = adapter
|
||||
addOnScrollListener(scrollListener)
|
||||
savedInstanceState?.getParcelable<AppDetailAdapter.SavedState>(STATE_ADAPTER)
|
||||
?.let(adapter::restoreState)
|
||||
layoutManagerState = savedInstanceState?.getParcelable(STATE_LAYOUT_MANAGER)
|
||||
recyclerView = this
|
||||
})
|
||||
|
||||
var first = true
|
||||
productDisposable = Observable.just(Unit)
|
||||
//.concatWith(Database.observable(Database.Subject.Products)) // TODO have to be replaced like whole rxJava
|
||||
.observeOn(Schedulers.io())
|
||||
.flatMapSingle {
|
||||
RxUtils.querySingle {
|
||||
screenActivity.db.productDao.get(packageName).filterNotNull()
|
||||
}
|
||||
}
|
||||
.flatMapSingle { products ->
|
||||
RxUtils
|
||||
.querySingle { screenActivity.db.repositoryDao.all }
|
||||
.map { it ->
|
||||
it.asSequence().map { Pair(it.id, it) }.toMap()
|
||||
.let {
|
||||
products.mapNotNull { product ->
|
||||
it[product.repositoryId]?.let {
|
||||
Pair(
|
||||
product,
|
||||
it
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.flatMapSingle { products ->
|
||||
RxUtils
|
||||
.querySingle { Nullable(screenActivity.db.installedDao.get(packageName)) }
|
||||
.map { Pair(products, it) }
|
||||
}
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { it ->
|
||||
val (products, installedItem) = it
|
||||
val firstChanged = first
|
||||
first = false
|
||||
val productChanged = this.products != products
|
||||
val installedItemChanged = this.installed?.data != installedItem.value
|
||||
if (firstChanged || productChanged || installedItemChanged) {
|
||||
layoutManagerState?.let {
|
||||
recyclerView?.layoutManager!!.onRestoreInstanceState(
|
||||
it
|
||||
)
|
||||
}
|
||||
layoutManagerState = null
|
||||
if (firstChanged || productChanged) {
|
||||
this.products = products
|
||||
}
|
||||
if (firstChanged || installedItemChanged) {
|
||||
installed = installedItem.value?.let {
|
||||
val isSystem = try {
|
||||
((requireContext().packageManager.getApplicationInfo(
|
||||
packageName,
|
||||
0
|
||||
).flags)
|
||||
and ApplicationInfo.FLAG_SYSTEM) != 0
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
val launcherActivities =
|
||||
if (packageName == requireContext().packageName) {
|
||||
// Don't allow to launch self
|
||||
emptyList()
|
||||
} else {
|
||||
val packageManager = requireContext().packageManager
|
||||
packageManager
|
||||
.queryIntentActivities(
|
||||
Intent(Intent.ACTION_MAIN).addCategory(
|
||||
Intent.CATEGORY_LAUNCHER
|
||||
), 0
|
||||
)
|
||||
.asSequence()
|
||||
.mapNotNull { resolveInfo -> resolveInfo.activityInfo }
|
||||
.filter { activityInfo -> activityInfo.packageName == packageName }
|
||||
.mapNotNull { activityInfo ->
|
||||
val label = try {
|
||||
activityInfo.loadLabel(packageManager).toString()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
label?.let { labelName ->
|
||||
Pair(
|
||||
activityInfo.name,
|
||||
labelName
|
||||
)
|
||||
}
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
Installed(it, isSystem, launcherActivities)
|
||||
}
|
||||
}
|
||||
val recyclerView = recyclerView!!
|
||||
val adapter = recyclerView.adapter as AppDetailAdapter
|
||||
if (firstChanged || productChanged || installedItemChanged) {
|
||||
adapter.setProducts(
|
||||
recyclerView.context,
|
||||
packageName,
|
||||
products,
|
||||
installedItem.value
|
||||
)
|
||||
}
|
||||
lifecycleScope.launch { updateButtons() }
|
||||
}
|
||||
}
|
||||
|
||||
downloadConnection.bind(requireContext())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
recyclerView = null
|
||||
|
||||
productDisposable?.dispose()
|
||||
productDisposable = null
|
||||
downloadConnection.unbind(requireContext())
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
||||
val layoutManagerState =
|
||||
layoutManagerState ?: recyclerView?.layoutManager?.onSaveInstanceState()
|
||||
layoutManagerState?.let { outState.putParcelable(STATE_LAYOUT_MANAGER, it) }
|
||||
val adapterState = (recyclerView?.adapter as? AppDetailAdapter)?.saveState()
|
||||
adapterState?.let { outState.putParcelable(STATE_ADAPTER, it) }
|
||||
}
|
||||
|
||||
private suspend fun updateButtons() {
|
||||
updateButtons(ProductPreferences[packageName])
|
||||
}
|
||||
|
||||
private suspend fun updateButtons(preference: ProductPreference) =
|
||||
withContext(Dispatchers.Default) {
|
||||
val installed = installed
|
||||
val product = findSuggestedProduct(products, installed?.data) { it.first }?.first
|
||||
val compatible = product != null && product.selectedReleases.firstOrNull()
|
||||
.let { it != null && it.incompatibilities.isEmpty() }
|
||||
val canInstall = product != null && installed == null && compatible
|
||||
val canUpdate =
|
||||
product != null && compatible && product.canUpdate(installed?.data) &&
|
||||
!preference.shouldIgnoreUpdate(product.versionCode)
|
||||
val canUninstall = product != null && installed != null && !installed.isSystem
|
||||
val canLaunch =
|
||||
product != null && installed != null && installed.launcherActivities.isNotEmpty()
|
||||
val canShare = product != null && products[0].second.name == "F-Droid"
|
||||
|
||||
val actions = mutableSetOf<Action>()
|
||||
launch {
|
||||
if (canInstall) {
|
||||
actions += Action.INSTALL
|
||||
}
|
||||
}
|
||||
launch {
|
||||
if (canUpdate) {
|
||||
actions += Action.UPDATE
|
||||
}
|
||||
}
|
||||
launch {
|
||||
if (canLaunch) {
|
||||
actions += Action.LAUNCH
|
||||
}
|
||||
}
|
||||
launch {
|
||||
if (installed != null) {
|
||||
actions += Action.DETAILS
|
||||
}
|
||||
}
|
||||
launch {
|
||||
if (canUninstall) {
|
||||
actions += Action.UNINSTALL
|
||||
}
|
||||
}
|
||||
launch {
|
||||
if (canShare) {
|
||||
actions += Action.SHARE
|
||||
}
|
||||
}
|
||||
val primaryAction = when {
|
||||
canUpdate -> Action.UPDATE
|
||||
canLaunch -> Action.LAUNCH
|
||||
canInstall -> Action.INSTALL
|
||||
installed != null -> Action.DETAILS
|
||||
canShare -> Action.SHARE
|
||||
else -> null
|
||||
}
|
||||
|
||||
launch(Dispatchers.Main) {
|
||||
val adapterAction =
|
||||
if (downloading) AppDetailAdapter.Action.CANCEL else primaryAction?.adapterAction
|
||||
(recyclerView?.adapter as? AppDetailAdapter)?.setAction(adapterAction)
|
||||
for (action in sequenceOf(
|
||||
Action.INSTALL,
|
||||
Action.SHARE,
|
||||
Action.UPDATE,
|
||||
Action.UNINSTALL
|
||||
)) {
|
||||
toolbar.menu.findItem(action.id).isEnabled = !downloading
|
||||
}
|
||||
}
|
||||
launch { this@AppDetailFragment.actions = Pair(actions, primaryAction) }
|
||||
launch(Dispatchers.Main) { updateToolbarButtons() }
|
||||
}
|
||||
|
||||
private suspend fun updateToolbarTitle() {
|
||||
withContext(Dispatchers.Main) {
|
||||
val showPackageName = recyclerView
|
||||
?.let { (it.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() != 0 } == true
|
||||
launch {
|
||||
collapsingToolbar.title =
|
||||
if (showPackageName) products[0].first.label.trimAfter(' ', 2)
|
||||
else getString(R.string.application)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateToolbarButtons() {
|
||||
withContext(Dispatchers.Default) {
|
||||
val (actions, primaryAction) = actions
|
||||
val showPrimaryAction = recyclerView
|
||||
?.let { (it.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() != 0 } == true
|
||||
val displayActions = actions.toMutableSet()
|
||||
launch {
|
||||
if (!showPrimaryAction && primaryAction != null) {
|
||||
displayActions -= primaryAction
|
||||
}
|
||||
}
|
||||
launch {
|
||||
if (displayActions.size >= 4 && resources.configuration.screenWidthDp < 400) {
|
||||
displayActions -= Action.DETAILS
|
||||
}
|
||||
}
|
||||
|
||||
launch(Dispatchers.Main) {
|
||||
for (action in Action.values())
|
||||
toolbar.menu.findItem(action.id).isVisible = action in displayActions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateDownloadState(state: DownloadService.State?) {
|
||||
val status = when (state) {
|
||||
is DownloadService.State.Pending -> AppDetailAdapter.Status.Pending
|
||||
is DownloadService.State.Connecting -> AppDetailAdapter.Status.Connecting
|
||||
is DownloadService.State.Downloading -> AppDetailAdapter.Status.Downloading(
|
||||
state.read,
|
||||
state.total
|
||||
)
|
||||
is DownloadService.State.Success, is DownloadService.State.Error, is DownloadService.State.Cancel, null -> null
|
||||
}
|
||||
val downloading = status != null
|
||||
if (this.downloading != downloading) {
|
||||
this.downloading = downloading
|
||||
updateButtons()
|
||||
}
|
||||
(recyclerView?.adapter as? AppDetailAdapter)?.setStatus(status)
|
||||
if (state is DownloadService.State.Success && isResumed && !rootInstallerEnabled) {
|
||||
withContext(Dispatchers.Default) {
|
||||
AppInstaller.getInstance(context)?.defaultInstaller?.install(state.release.cacheFileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val scrollListener = object : RecyclerView.OnScrollListener() {
|
||||
private var lastPosition = -1
|
||||
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
val position =
|
||||
(recyclerView.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
|
||||
val lastPosition = lastPosition
|
||||
this.lastPosition = position
|
||||
if ((lastPosition == 0) != (position == 0)) {
|
||||
lifecycleScope.launch {
|
||||
launch { updateToolbarTitle() }
|
||||
launch { updateToolbarButtons() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActionClick(action: AppDetailAdapter.Action) {
|
||||
when (action) {
|
||||
AppDetailAdapter.Action.INSTALL,
|
||||
AppDetailAdapter.Action.UPDATE,
|
||||
-> {
|
||||
val installedItem = installed?.data
|
||||
lifecycleScope.launch {
|
||||
startUpdate(
|
||||
packageName,
|
||||
installedItem,
|
||||
products,
|
||||
downloadConnection
|
||||
)
|
||||
}
|
||||
Unit
|
||||
}
|
||||
AppDetailAdapter.Action.LAUNCH -> {
|
||||
val launcherActivities = installed?.launcherActivities.orEmpty()
|
||||
if (launcherActivities.size >= 2) {
|
||||
LaunchDialog(launcherActivities).show(
|
||||
childFragmentManager,
|
||||
LaunchDialog::class.java.name
|
||||
)
|
||||
} else {
|
||||
launcherActivities.firstOrNull()?.let { startLauncherActivity(it.first) }
|
||||
}
|
||||
Unit
|
||||
}
|
||||
AppDetailAdapter.Action.DETAILS -> {
|
||||
startActivity(
|
||||
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||
.setData(Uri.parse("package:$packageName"))
|
||||
)
|
||||
}
|
||||
AppDetailAdapter.Action.UNINSTALL -> {
|
||||
lifecycleScope.launch {
|
||||
AppInstaller.getInstance(context)?.defaultInstaller?.uninstall(packageName)
|
||||
}
|
||||
Unit
|
||||
}
|
||||
AppDetailAdapter.Action.CANCEL -> {
|
||||
val binder = downloadConnection.binder
|
||||
if (downloading && binder != null) {
|
||||
binder.cancel(packageName)
|
||||
} else Unit
|
||||
}
|
||||
AppDetailAdapter.Action.SHARE -> {
|
||||
shareIntent(packageName, products[0].first.label)
|
||||
}
|
||||
}::class
|
||||
}
|
||||
|
||||
private fun startLauncherActivity(name: String) {
|
||||
try {
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_MAIN)
|
||||
.addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
.setComponent(ComponentName(packageName, name))
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun shareIntent(packageName: String, appName: String) {
|
||||
val shareIntent = Intent(Intent.ACTION_SEND)
|
||||
val extraText = if (Android.sdk(24)) {
|
||||
"https://www.f-droid.org/${resources.configuration.locales[0].language}/packages/${packageName}/"
|
||||
} else "https://www.f-droid.org/${resources.configuration.locale.language}/packages/${packageName}/"
|
||||
|
||||
|
||||
shareIntent.type = "text/plain"
|
||||
shareIntent.putExtra(Intent.EXTRA_TITLE, appName)
|
||||
shareIntent.putExtra(Intent.EXTRA_SUBJECT, appName)
|
||||
shareIntent.putExtra(Intent.EXTRA_TEXT, extraText)
|
||||
|
||||
startActivity(Intent.createChooser(shareIntent, "Where to Send?"))
|
||||
}
|
||||
|
||||
override fun onPreferenceChanged(preference: ProductPreference) {
|
||||
lifecycleScope.launch { updateButtons(preference) }
|
||||
}
|
||||
|
||||
override fun onPermissionsClick(group: String?, permissions: List<String>) {
|
||||
MessageDialog(MessageDialog.Message.Permissions(group, permissions)).show(
|
||||
childFragmentManager
|
||||
)
|
||||
}
|
||||
|
||||
override fun onScreenshotClick(screenshot: Screenshot) {
|
||||
val pair = products.asSequence()
|
||||
.map { it ->
|
||||
Pair(
|
||||
it.second,
|
||||
it.first.screenshots.find { it === screenshot }?.identifier
|
||||
)
|
||||
}
|
||||
.filter { it.second != null }.firstOrNull()
|
||||
if (pair != null) {
|
||||
val (repository, identifier) = pair
|
||||
if (identifier != null) {
|
||||
ScreenshotsFragment(packageName, repository.id, identifier).show(
|
||||
childFragmentManager
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onReleaseClick(release: Release) {
|
||||
val installedItem = installed?.data
|
||||
when {
|
||||
release.incompatibilities.isNotEmpty() -> {
|
||||
MessageDialog(
|
||||
MessageDialog.Message.ReleaseIncompatible(
|
||||
release.incompatibilities,
|
||||
release.platforms, release.minSdkVersion, release.maxSdkVersion
|
||||
)
|
||||
).show(childFragmentManager)
|
||||
}
|
||||
installedItem != null && installedItem.versionCode > release.versionCode -> {
|
||||
MessageDialog(MessageDialog.Message.ReleaseOlder).show(childFragmentManager)
|
||||
}
|
||||
installedItem != null && installedItem.signature != release.signature -> {
|
||||
MessageDialog(MessageDialog.Message.ReleaseSignatureMismatch).show(
|
||||
childFragmentManager
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
val productRepository =
|
||||
products.asSequence().filter { it -> it.first.releases.any { it === release } }
|
||||
.firstOrNull()
|
||||
if (productRepository != null) {
|
||||
downloadConnection.binder?.enqueue(
|
||||
packageName, productRepository.first.label,
|
||||
productRepository.second, release
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUriClick(uri: Uri, shouldConfirm: Boolean): Boolean {
|
||||
return if (shouldConfirm && (uri.scheme == "http" || uri.scheme == "https")) {
|
||||
MessageDialog(MessageDialog.Message.Link(uri)).show(childFragmentManager)
|
||||
true
|
||||
} else {
|
||||
try {
|
||||
startActivity(Intent(Intent.ACTION_VIEW, uri))
|
||||
true
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
e.printStackTrace()
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LaunchDialog() : DialogFragment() {
|
||||
companion object {
|
||||
private const val EXTRA_NAMES = "names"
|
||||
private const val EXTRA_LABELS = "labels"
|
||||
}
|
||||
|
||||
constructor(launcherActivities: List<Pair<String, String>>) : this() {
|
||||
arguments = Bundle().apply {
|
||||
putStringArrayList(EXTRA_NAMES, ArrayList(launcherActivities.map { it.first }))
|
||||
putStringArrayList(EXTRA_LABELS, ArrayList(launcherActivities.map { it.second }))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): AlertDialog {
|
||||
val names = requireArguments().getStringArrayList(EXTRA_NAMES)!!
|
||||
val labels = requireArguments().getStringArrayList(EXTRA_LABELS)!!
|
||||
return MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.launch)
|
||||
.setItems(labels.toTypedArray()) { _, position ->
|
||||
(parentFragment as AppDetailFragment)
|
||||
.startLauncherActivity(names[position])
|
||||
}
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.create()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user