16
16
17
17
package com.example.background.workers.filters
18
18
19
- import android.app.NotificationManager
19
+ import android.app.ForegroundServiceStartNotAllowedException
20
20
import android.content.Context
21
21
import android.graphics.Bitmap
22
22
import android.graphics.BitmapFactory
23
23
import android.net.Uri
24
24
import android.util.Log
25
25
import androidx.annotation.VisibleForTesting
26
- import androidx.work.*
26
+ import androidx.core.os.BuildCompat
27
+ import androidx.work.CoroutineWorker
28
+ import androidx.work.ForegroundInfo
29
+ import androidx.work.WorkerParameters
30
+ import androidx.work.workDataOf
27
31
import com.example.background.Constants
28
32
import com.example.background.library.R
29
33
import com.example.background.workers.createNotification
@@ -38,8 +42,8 @@ abstract class BaseFilterWorker(context: Context, parameters: WorkerParameters)
38
42
CoroutineWorker (context, parameters) {
39
43
40
44
override suspend fun doWork (): Result {
41
- val resourceUri = inputData.getString(Constants .KEY_IMAGE_URI ) ? :
42
- throw IllegalArgumentException (" Invalid input uri" )
45
+ val resourceUri = inputData.getString(Constants .KEY_IMAGE_URI )
46
+ ? : throw IllegalArgumentException (" Invalid input uri" )
43
47
return try {
44
48
val inputStream = inputStreamFor(applicationContext, resourceUri)
45
49
val bitmap = BitmapFactory .decodeStream(inputStream)
@@ -50,6 +54,19 @@ abstract class BaseFilterWorker(context: Context, parameters: WorkerParameters)
50
54
} catch (fileNotFoundException: FileNotFoundException ) {
51
55
Log .e(TAG , " Failed to decode input stream" , fileNotFoundException)
52
56
Result .failure()
57
+ } catch (e: IllegalStateException ) {
58
+ // Check if this is a ForegroundServiceStartNotAllowedException and handle accordingly.
59
+ val isForegroundStartNotAllowed =
60
+ BuildCompat .isAtLeastS() && e is ForegroundServiceStartNotAllowedException
61
+ val logMessage = if (isForegroundStartNotAllowed) {
62
+ " Couldn't start a foreground service"
63
+ } else {
64
+ " An error occured"
65
+ }
66
+ Log .e(TAG , logMessage, e)
67
+ // TODO Handle depending on the Worker's use case.
68
+ // e.g. Batch long running work, clean up work or in this example fail the worker.
69
+ Result .failure()
53
70
} catch (throwable: Throwable ) {
54
71
Log .e(TAG , " Error applying filter" , throwable)
55
72
Result .failure()
@@ -95,13 +112,18 @@ abstract class BaseFilterWorker(context: Context, parameters: WorkerParameters)
95
112
* Create ForegroundInfo required to run a Worker in a foreground service.
96
113
*/
97
114
override suspend fun getForegroundInfo (): ForegroundInfo {
98
- return ForegroundInfo (NOTIFICATION_ID , createNotification(applicationContext, id,
99
- applicationContext.getString(R .string.notification_title_filtering_image)))
115
+ return ForegroundInfo (
116
+ NOTIFICATION_ID , createNotification(
117
+ applicationContext, id,
118
+ applicationContext.getString(R .string.notification_title_filtering_image)
119
+ )
120
+ )
100
121
}
101
122
102
123
companion object {
103
124
const val TAG = " BaseFilterWorker"
104
125
const val ASSET_PREFIX = " file:///android_asset/"
126
+
105
127
// For a real world app you might want to use a different id for each Notification.
106
128
const val NOTIFICATION_ID = 1
107
129
0 commit comments