Fix WorkManager crash on android 11 and below
This commit is contained in:
@ -14,6 +14,8 @@ import androidx.compose.foundation.layout.*
|
|||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Alignment.Companion.BottomCenter
|
||||||
import androidx.compose.ui.Alignment.Companion.TopCenter
|
import androidx.compose.ui.Alignment.Companion.TopCenter
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
@ -56,7 +58,7 @@ class SaveSheetActivity : AppCompatActivity() {
|
|||||||
if (intent.type?.startsWith("text/plain") == true) {
|
if (intent.type?.startsWith("text/plain") == true) {
|
||||||
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
|
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
|
||||||
extractedText = it
|
extractedText = it
|
||||||
workManager.enqueueSaveWorker(this, it)
|
workManager.enqueueSaveWorker(it)
|
||||||
Log.d(ContentValues.TAG, "Extracted text: $extractedText")
|
Log.d(ContentValues.TAG, "Extracted text: $extractedText")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +77,7 @@ class SaveSheetActivity : AppCompatActivity() {
|
|||||||
setContent {
|
setContent {
|
||||||
LaunchedEffect(extractedText) {
|
LaunchedEffect(extractedText) {
|
||||||
extractedText?.let { url ->
|
extractedText?.let { url ->
|
||||||
workManager.getWorkInfosByTagFlow(url).map {
|
workManager.getWorkInfosForUniqueWorkFlow(url).map {
|
||||||
saveState = when (it.firstOrNull()?.state) {
|
saveState = when (it.firstOrNull()?.state) {
|
||||||
WorkInfo.State.RUNNING -> SaveState.SAVING
|
WorkInfo.State.RUNNING -> SaveState.SAVING
|
||||||
WorkInfo.State.SUCCEEDED -> SaveState.SAVED
|
WorkInfo.State.SUCCEEDED -> SaveState.SAVED
|
||||||
@ -86,7 +88,6 @@ class SaveSheetActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val scaffoldState: ScaffoldState = rememberScaffoldState()
|
|
||||||
val message = when (saveState) {
|
val message = when (saveState) {
|
||||||
SaveState.DEFAULT -> ""
|
SaveState.DEFAULT -> ""
|
||||||
SaveState.SAVING -> "Saved to Omnivore"
|
SaveState.SAVING -> "Saved to Omnivore"
|
||||||
@ -94,35 +95,30 @@ class SaveSheetActivity : AppCompatActivity() {
|
|||||||
SaveState.SAVED -> "Saved to Omnivore"
|
SaveState.SAVED -> "Saved to Omnivore"
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Box(
|
||||||
modifier = Modifier.clickable {
|
Modifier
|
||||||
Log.d("debug", "DISMISS SCAFFOLD")
|
.background(Color.Transparent)
|
||||||
exit()
|
.fillMaxSize()
|
||||||
},
|
.clickable {
|
||||||
scaffoldState = scaffoldState,
|
Log.d("debug", "DISMISS BOX")
|
||||||
backgroundColor = Color.Transparent,
|
exit()
|
||||||
|
}
|
||||||
// TODO: In future versions we can present Label, Note, Highlight options here
|
|
||||||
bottomBar = {
|
|
||||||
|
|
||||||
androidx.compose.material3.BottomAppBar(
|
|
||||||
|
|
||||||
modifier = Modifier
|
|
||||||
.height(55.dp)
|
|
||||||
.fillMaxWidth()
|
|
||||||
.clip(RoundedCornerShape(topEnd = 5.dp, topStart = 5.dp)),
|
|
||||||
containerColor = MaterialTheme.colors.background,
|
|
||||||
actions = {
|
|
||||||
Spacer(modifier = Modifier.width(25.dp))
|
|
||||||
Text(
|
|
||||||
message,
|
|
||||||
style = androidx.compose.material3.MaterialTheme.typography.titleMedium
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
|
Row(
|
||||||
|
Modifier
|
||||||
|
.align(BottomCenter)
|
||||||
|
.height(55.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(RoundedCornerShape(topEnd = 5.dp, topStart = 5.dp))
|
||||||
|
.background(MaterialTheme.colors.background)
|
||||||
|
.padding(start = 25.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
message,
|
||||||
|
style = androidx.compose.material3.MaterialTheme.typography.titleMedium
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(saveState) {
|
LaunchedEffect(saveState) {
|
||||||
@ -134,25 +130,30 @@ class SaveSheetActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun WorkManager.enqueueSaveWorker(context: Context, url: String) {
|
private fun WorkManager.enqueueSaveWorker(url: String) {
|
||||||
val saveData = workDataOf("url" to url)
|
val saveData = workDataOf("url" to url)
|
||||||
|
|
||||||
val saveWork = OneTimeWorkRequestBuilder<SaveURLWorker>()
|
val saveWork = OneTimeWorkRequestBuilder<SaveURLWorker>()
|
||||||
.setInputData(saveData)
|
.setInputData(saveData)
|
||||||
.setConstraints(Constraints.Builder()
|
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
.setConstraints(
|
||||||
.build())
|
Constraints.Builder()
|
||||||
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val syncWork = OneTimeWorkRequestBuilder<LibrarySyncWorker>()
|
val syncWork = OneTimeWorkRequestBuilder<LibrarySyncWorker>()
|
||||||
.setConstraints(Constraints.Builder()
|
.setConstraints(
|
||||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
Constraints.Builder()
|
||||||
.build())
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
.setInitialDelay(5, TimeUnit.SECONDS)
|
.setInitialDelay(5, TimeUnit.SECONDS)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
WorkManager.getInstance(context)
|
// using url as name because requests with a different url might not be completed yet
|
||||||
.beginUniqueWork("saveAndSync", ExistingWorkPolicy.REPLACE, saveWork)
|
beginUniqueWork(url, ExistingWorkPolicy.REPLACE, saveWork)
|
||||||
.then(syncWork)
|
.then(syncWork)
|
||||||
.enqueue()
|
.enqueue()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,4 +101,51 @@ class SaveURLWorker @AssistedInject constructor(
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val NOTIFICATION_CHANNEL_ID = "SAVE_URL_WORKER_CHANNEL"
|
||||||
|
const val NOTIFICATION_CHANNEL_NAME = "URL Saver"
|
||||||
|
const val NOTIFICATION_ID = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getForegroundInfo(): ForegroundInfo {
|
||||||
|
val notification = createNotification()
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
ForegroundInfo(
|
||||||
|
NOTIFICATION_ID,
|
||||||
|
notification,
|
||||||
|
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ForegroundInfo(NOTIFICATION_ID, notification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNotification(): Notification {
|
||||||
|
val channelId =
|
||||||
|
createNotificationChannel()
|
||||||
|
|
||||||
|
return NotificationCompat.Builder(applicationContext, channelId)
|
||||||
|
.setContentTitle("Saving URL")
|
||||||
|
.setContentText("Your URL is being saved in the background.")
|
||||||
|
.setSmallIcon(R.drawable.ic_notification) // Ensure this icon is valid
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNotificationChannel(): String {
|
||||||
|
val channel = NotificationChannel(
|
||||||
|
NOTIFICATION_CHANNEL_ID,
|
||||||
|
NOTIFICATION_CHANNEL_NAME,
|
||||||
|
NotificationManager.IMPORTANCE_HIGH // Changed from LOW to HIGH
|
||||||
|
).apply {
|
||||||
|
description = "Notification channel for URL saving"
|
||||||
|
}
|
||||||
|
|
||||||
|
val notificationManager =
|
||||||
|
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
notificationManager.createNotificationChannel(channel)
|
||||||
|
|
||||||
|
return NOTIFICATION_CHANNEL_ID
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user