Обновления фонового работника не удаляют исходного работника. (Android Studio — Jetpack Compose/Kotlin)Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Обновления фонового работника не удаляют исходного работника. (Android Studio — Jetpack Compose/Kotlin)

Сообщение Anonymous »

У меня есть фоновый работник, который я переключаю в одном месте, но могу добавить фильтр постфактум в другом месте. Когда я добавляю фильтр, я пытаюсь обновить и/или удалить исходного работника, если он существует, но, похоже, он не обновляется. Я даже пробовал полностью удалить обновление (которое возвращает работника) и заменил его элементами prune и/или cancelAllWork, которые отменяют работу. Затем я раскомментирую логику обновления, и это снова приводит к простому добавлению другого без отмены оригинала. Если оставить это в покое, могут остаться стопки рабочих. Кажется, что при перезапуске приложения лишних рабочих нет. Однако на самом деле это не решает проблему.
Почему этот код не работает должным образом?
Справедливое предупреждение: я знаю, что этот код — бардак. .
Менеджер уведомлений

Код: Выделить всё

class NotificationHandler : ComponentActivity() {
private val CHANNEL_ID = "posts"
private val SHARED_PREF_NAME = "notification_prefs"

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
NotificationContent()
}
}

@Composable
fun NotificationContent() {
val context = LocalContext.current
var hasNotificationPermission by rememberSaveable {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
mutableStateOf(
ContextCompat.checkSelfPermission(
context,
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
)
} else {mutableStateOf(true)}
}

val workManager = WorkManager.getInstance(this)

var notificationToggle by rememberSaveable{
mutableStateOf(getNotificationToggleState(context))
}

val launcher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission(),
onResult = { isGranted ->
hasNotificationPermission = isGranted
}
)

if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) &&  !hasNotificationPermission) {
Button(
onClick = {
launcher.launch(Manifest.permission.POST_NOTIFICATIONS)
},
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary
)
) {
Text(text = "Request Notification Permission")
}
}

if (hasNotificationPermission) {
Row(verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth()
) {
Text("Toggle Notifications", color = MaterialTheme.colorScheme.onSurface, fontWeight = FontWeight.Bold)
Spacer(Modifier.weight(1f))
Switch(
modifier = Modifier.scale(1.3f),
checked = notificationToggle,
onCheckedChange = { newToggleState ->
notificationToggle = newToggleState
if (newToggleState) {
workManager.enqueueUniquePeriodicWork(
"updateCheckRequest",
ExistingPeriodicWorkPolicy.UPDATE,
updateCheckRequest
)
} else {
workManager.cancelAllWork()
workManager.pruneWork()
}
saveNotificationToggleState(context, newToggleState)
}
)
}
}

}

private fun getNotificationToggleState(context: Context): Boolean {
val sharedPreferences: SharedPreferences = context.getSharedPreferences(SHARED_PREF_NAME, MODE_PRIVATE)
return sharedPreferences.getBoolean("notification_toggle", false)
}

private fun saveNotificationToggleState(context: Context, state: Boolean) {
val sharedPreferences: SharedPreferences = context.getSharedPreferences(SHARED_PREF_NAME, MODE_PRIVATE)
with(sharedPreferences.edit()) {
putBoolean("notification_toggle", state)
apply()
}
}
}
Фильтр

Код: Выделить всё

class Filter(private val context: Context) {
private val sharedPreferences = context.getSharedPreferences("ExclusionPrefs", Context.MODE_PRIVATE)
private var filter = sharedPreferences.getStringSet("filter", HashSet()) ?: HashSet()
private var filterText = sharedPreferences.getString("filterText", "") ?: ""

private var textToSave by mutableStateOf("")
private var editingFilters by mutableStateOf(false)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun FilterContent(){
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth()
) {
Text(
"Add/Edit Filters",
color = MaterialTheme.colorScheme.onSurface,
fontWeight = FontWeight.Bold
)
Spacer(Modifier.weight(1f))
Button(
onClick = {editingFilters = true},
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary
)
) {
Icon(
painter = painterResource(id = R.drawable.filter_icon),
contentDescription = "Filter",
tint = MaterialTheme.colorScheme.onPrimary
)
}
}
if (editingFilters) {
if (filterText != "") {
Text("Current Filter:  $filterText", fontStyle = FontStyle.Italic, modifier = Modifier.padding(bottom = 8.dp))
}

TextField(
value = textToSave,
onValueChange = { textToSave = it },
label = { Text("Separate By Comma(s)") },
placeholder = { Text("Epic, (DLC), [PSA], etc.") },
singleLine = true,
keyboardActions = KeyboardActions(
onDone = {
saveTextToSharedPreferences(textToSave)
editingFilters = false
}
)
)

if (filterText != "") {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth()
) {
Text(
"Delete All Filters?",
color = MaterialTheme.colorScheme.onSurface,
fontWeight = FontWeight.Bold
)
Spacer(Modifier.weight(1f))
Button(
onClick = {
saveTextToSharedPreferences("")
editingFilters = false},
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary
)
) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = "Delete Filters",
tint = MaterialTheme.colorScheme.onPrimary
)
}
}
}
}
}

private fun saveTextToSharedPreferences(text: String) {
if (text != "") {
val keywords = text.split(",").map { it.trim() }.toSet()
filter = HashSet() // Clearing the old
filterText = "" // Clearing the old
filter = HashSet(filter + keywords)  // Update the filter set with the new keywords
sharedPreferences.edit {
putString("filterText", text)
putStringSet("filter", filter)
}

// Only runs if notifications are enabled
val workManager = WorkManager.getInstance(context)
val workInfos = workManager.getWorkInfosForUniqueWork("updateCheckRequest").get()
if (workInfos.isNotEmpty()) {
workManager.cancelAllWork() // Added during testing
workManager.pruneWork() // Added during testing
// Specifically where the problem is
workManager.enqueueUniquePeriodicWork(
"updateCheckRequest",
ExistingPeriodicWorkPolicy.UPDATE,
updateCheckRequest
)
}
}
else {
filter = HashSet() // Clearing the old
filterText = ""  // Clearing the old
sharedPreferences.edit{
putStringSet("filter", HashSet())
putString("filterText", "")
}

// Only runs if notifications are enabled
val workManager = WorkManager.getInstance(context)
val workInfos = workManager.getWorkInfosForUniqueWork("updateCheckRequest").get()
if (workInfos.isNotEmpty()) {
workManager.cancelAllWork() // Added during testing
workManager.pruneWork() // Added during testing
// Specifically where the problem is
workManager.enqueueUniquePeriodicWork(
"updateCheckRequest",
ExistingPeriodicWorkPolicy.UPDATE,
updateCheckRequest
)
}
}
}
}
UpdateWorkerCheck

Код: Выделить всё

class UpdateCheckWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
try {

val appContext = applicationContext

val sharedPreferences = appContext.getSharedPreferences("ExclusionPrefs", Context.MODE_PRIVATE)
val filter = sharedPreferences.getStringSet("filter", HashSet()) ?: HashSet()

val intent = Intent(appContext, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
val pendingIntent: PendingIntent = PendingIntent.getActivity(
appContext,
1,
intent,
PendingIntent.FLAG_IMMUTABLE
)

data class CheckItem(val title: String, val id: String)

val retrofit = Retrofit.Builder()
.baseUrl("https://www.reddit.com/r/")
.addConverterFactory(GsonConverterFactory.create())
.build()

val retrofitAPI = retrofit.create(RetroFitAPI::class.java)
val response = retrofitAPI.getData().execute()

if (response.isSuccessful) {
val db_li = LatestDatabase.getInstance(appContext)
if (db_li.latestItemDao().getAll() == null) { return Result.failure()}

val data = response.body()
data?.let {
val check = it.data.children.map { child ->
CheckItem(title = child.data.title, id = child.data.id)
}.filterNot { check -> filter.any { keyword ->  check.title.contains(keyword, ignoreCase = true) } }

var notificationId = (0..1000).random() // This should prob be a static int but I don't want it to be overwritten

GlobalScope.launch(Dispatchers.IO) {
// Added precaution
delay(20000)

check.take(3).forEach { check ->
if (db_li.latestItemDao().getLatestItemById(check.id) == null) {
db_li.latestItemDao().insert(LatestItem(check.id))
val notification =
NotificationCompat.Builder(appContext, "posts")
.setSmallIcon(R.drawable.logo_whiteout)
.setContentTitle("New Post Is Live!")
.setContentText(check.title)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build()
val notificationManager = ContextCompat.getSystemService(
appContext,
NotificationManager::class.java
)
notificationManager?.notify(notificationId, notification)
notificationId++
}
}
}
}
}
return Result.success()
} catch (e: Exception) {
return Result.failure()
}
}
}

// Schedule the worker to run periodically
val updateCheckRequest = PeriodicWorkRequestBuilder(5, TimeUnit.MINUTES)
.setConstraints(Constraints(NetworkType.CONNECTED))
.setInitialDelay(1, TimeUnit.MINUTES)
.build()
Спасибо за информацию.

Подробнее здесь: https://stackoverflow.com/questions/778 ... studio-jet
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»