Update
This commit is contained in:
parent
91903e5282
commit
e88efe5f2d
5 changed files with 61 additions and 30 deletions
|
@ -18,7 +18,6 @@ import eu.m724.pojavbackup.core.backup.Backup.BackupStatus
|
|||
import eu.m724.pojavbackup.core.data.GameDataRepository
|
||||
import eu.m724.pojavbackup.core.datastore.SettingsRepository
|
||||
import eu.m724.pojavbackup.notification.NotificationChannels
|
||||
import kotlinx.coroutines.delay
|
||||
import org.apache.commons.compress.compressors.CompressorStreamFactory
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
@ -50,8 +49,6 @@ class BackupWorker @AssistedInject constructor(
|
|||
|
||||
updateStatus("Initializing")
|
||||
|
||||
delay(10000)
|
||||
|
||||
val settings = settingsRepository.getSettings()
|
||||
val worldIds = settingsRepository.getIncludedWorldIds(settings.worldOrder)
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.core.content.ContextCompat.startActivity
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavDestination.Companion.hierarchy
|
||||
import androidx.navigation.compose.NavHost
|
||||
|
@ -43,8 +45,8 @@ import eu.m724.pojavbackup.home.screen.HomeScreen
|
|||
import eu.m724.pojavbackup.home.screen.dashboard.DashboardScreen
|
||||
import eu.m724.pojavbackup.home.screen.history.HistoryScreen
|
||||
import eu.m724.pojavbackup.settings.SettingsActivity
|
||||
import eu.m724.pojavbackup.setup.SetupActivity
|
||||
import eu.m724.pojavbackup.ui.theme.PojavBackupTheme
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@AndroidEntryPoint
|
||||
class HomeActivity : ComponentActivity() {
|
||||
|
@ -62,8 +64,8 @@ class HomeActivity : ComponentActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
|
||||
viewModel.load(
|
||||
onSetupNeeded = {
|
||||
setupResult.launch(Intent(applicationContext, SetupActivity::class.java))
|
||||
onSetupRequired = {
|
||||
setupResult.launch(it)
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package eu.m724.pojavbackup.home
|
||||
|
||||
import android.Manifest
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
|
@ -12,6 +16,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
|
|||
import eu.m724.pojavbackup.core.data.GameDataRepository
|
||||
import eu.m724.pojavbackup.core.datastore.SettingsRepository
|
||||
import eu.m724.pojavbackup.notification.NotificationChannels
|
||||
import eu.m724.pojavbackup.setup.SetupActivity
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
@ -38,14 +43,20 @@ class HomeViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun load(
|
||||
onSetupNeeded: () -> Unit
|
||||
onSetupRequired: (Intent) -> Unit
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
val uri = settingsRepository.getSource()
|
||||
|
||||
if (uri == null || !checkForStoragePermission(uri)) {
|
||||
// TODO there could be that only one or two permissions are missing
|
||||
onSetupNeeded()
|
||||
val storagePermission = uri?.let { checkForStoragePermission(uri) } == true
|
||||
val notificationPermission = checkForNotificationPermission()
|
||||
|
||||
if (!storagePermission || !notificationPermission) {
|
||||
val intent = Intent(appContext, SetupActivity::class.java)
|
||||
.putExtra("storagePermissionGranted", storagePermission)
|
||||
.putExtra("notificationPermissionGranted", notificationPermission)
|
||||
|
||||
onSetupRequired(intent)
|
||||
} else {
|
||||
_uiState.update { it.copy(loading = false) }
|
||||
}
|
||||
|
@ -75,4 +86,9 @@ class HomeViewModel @Inject constructor(
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun checkForNotificationPermission(): Boolean {
|
||||
// TODO check if rejected
|
||||
return ContextCompat.checkSelfPermission(appContext, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package eu.m724.pojavbackup.setup
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
|
@ -37,7 +38,7 @@ class SetupActivity : ComponentActivity() {
|
|||
private val viewModel: SetupViewModel by viewModels()
|
||||
|
||||
private val openDocumentTree = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {
|
||||
viewModel.onOpenDocumentTree(applicationContext, it) { success ->
|
||||
viewModel.onOpenDocumentTree(it) { success ->
|
||||
if (success) {
|
||||
onComplete()
|
||||
} else {
|
||||
|
@ -51,16 +52,18 @@ class SetupActivity : ComponentActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private val notificationGrant = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
|
||||
if (isGranted) {
|
||||
onComplete()
|
||||
} else {
|
||||
// TODO instead red text?
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
"This is not a PojavLauncher directory.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
private val notificationGrant = registerForActivityResult(ActivityResultContracts.RequestPermission()) {
|
||||
viewModel.onNotificationGrant(it) { success ->
|
||||
if (success) {
|
||||
onComplete()
|
||||
} else {
|
||||
// TODO instead red text?
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
"This is not a PojavLauncher directory.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +98,7 @@ class SetupActivity : ComponentActivity() {
|
|||
openDocumentTree.launch(defaultUri)
|
||||
},
|
||||
onNotificationPermissionGrantClick = {
|
||||
openDocumentTree.launch(defaultUri)
|
||||
notificationGrant.launch(Manifest.permission.POST_NOTIFICATIONS)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -134,7 +137,7 @@ fun SetupScreen(
|
|||
GrantCard(
|
||||
title = "Notification permission",
|
||||
description = "It's needed to notify you about backup status.",
|
||||
granted = uiState.storagePermissionGranted,
|
||||
granted = uiState.notificationPermissionGranted,
|
||||
onClick = onNotificationPermissionGrantClick
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package eu.m724.pojavbackup.setup
|
|||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.PackageManager.NameNotFoundException
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
|
@ -10,6 +9,7 @@ import androidx.documentfile.provider.DocumentFile
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import eu.m724.pojavbackup.core.datastore.SettingsRepository
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
@ -20,6 +20,7 @@ import javax.inject.Inject
|
|||
|
||||
@HiltViewModel
|
||||
class SetupViewModel @Inject constructor(
|
||||
@ApplicationContext private val appContext: Context,
|
||||
private val settingsRepository: SettingsRepository
|
||||
) : ViewModel() {
|
||||
private val TAG: String = javaClass.name
|
||||
|
@ -51,16 +52,16 @@ class SetupViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
// TODO we could make the check call separate and not pass context here
|
||||
fun onOpenDocumentTree(context: Context, uri: Uri?, result: (Boolean) -> Unit) {
|
||||
fun onOpenDocumentTree(uri: Uri?, result: (Boolean) -> Unit) {
|
||||
if (uri != null) {
|
||||
Log.i(TAG, "Got URI: $uri")
|
||||
|
||||
context.contentResolver.takePersistableUriPermission(
|
||||
appContext.contentResolver.takePersistableUriPermission(
|
||||
uri,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
val hasPermission = checkForStoragePermission(context, uri)
|
||||
val hasPermission = checkForStoragePermission(uri)
|
||||
|
||||
viewModelScope.launch {
|
||||
if (hasPermission) {
|
||||
|
@ -72,11 +73,21 @@ class SetupViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun checkForStoragePermission(context: Context, uri: Uri): Boolean {
|
||||
fun onNotificationGrant(isGranted: Boolean, result: (Boolean) -> Unit) {
|
||||
if (isGranted) {
|
||||
_uiState.update {
|
||||
it.copy(notificationPermissionGranted = true)
|
||||
}
|
||||
}
|
||||
|
||||
result(isGranted)
|
||||
}
|
||||
|
||||
fun checkForStoragePermission(uri: Uri): Boolean {
|
||||
Log.i(TAG, "Checking for storage permission...")
|
||||
|
||||
// TODO Is this the right way? This isn't in https://developer.android.com/training/data-storage/shared/documents-files
|
||||
val directory = DocumentFile.fromTreeUri(context, uri)
|
||||
val directory = DocumentFile.fromTreeUri(appContext, uri)
|
||||
|
||||
if (directory == null || !directory.isDirectory) {
|
||||
Log.i(TAG, "No permission or not a directory")
|
||||
|
@ -100,7 +111,9 @@ class SetupViewModel @Inject constructor(
|
|||
return true
|
||||
}
|
||||
|
||||
fun detectInstalledLauncherPackage(packageManager: PackageManager): List<String> {
|
||||
fun detectInstalledLauncherPackage(): List<String> {
|
||||
val packageManager = appContext.packageManager
|
||||
|
||||
return POJAV_PACKAGES.filter {
|
||||
try {
|
||||
packageManager.getPackageInfo(it, 0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue