diff --git a/README.md b/README.md
index 7f26ccf5..d015fb9d 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ You are also safe if your app is put in the background. All the uploads will con
Bear in mind that if you kill your app, the service gets killed as well, as it's attached to your app's process and all the currently running uploads will be terminated abruptly.
## Features
-* Android 5.0 (API 21) to Android 13 (API 33) support.
+* Android 5.0 (API 21) to Android 14 (API 34) support.
* *Android 13 Note, for apps targeting API 33 or newer*:
* Due to new behavior changes, you are [required to request POST_NOTIFICATIONS permission at runtime in your app](https://developer.android.com/develop/ui/views/notifications/notification-permission) or else the upload progress won't be shown. To see an example, please look at the BaseActivity in the `examples/app` folder.
* *Android 12 Note, for apps targeting API 31 or newer*:
diff --git a/examples/app/.idea/gradle.xml b/examples/app/.idea/gradle.xml
index e784d877..0a6543ae 100644
--- a/examples/app/.idea/gradle.xml
+++ b/examples/app/.idea/gradle.xml
@@ -8,7 +8,7 @@
-
+
diff --git a/manifest.gradle b/manifest.gradle
index 212055a0..b68a1a58 100644
--- a/manifest.gradle
+++ b/manifest.gradle
@@ -12,7 +12,7 @@ ext {
library_version = '4.8.0'
version_code = 49
min_sdk = 21
- target_sdk = 33
+ target_sdk = 34
demo_app_id = 'net.gotev.uploadservicedemo'
// Gradle classpath dependencies versions
diff --git a/uploadservice-ftp/build.gradle b/uploadservice-ftp/build.gradle
index a49eeb66..de824f83 100644
--- a/uploadservice-ftp/build.gradle
+++ b/uploadservice-ftp/build.gradle
@@ -69,7 +69,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- api 'commons-net:commons-net:3.8.0'
+ api 'commons-net:commons-net:3.10.0'
//api "net.gotev:uploadservice:${version}"
//comment the previous line and uncomment the next line for development (it uses the local lib)
api project(':uploadservice')
diff --git a/uploadservice-okhttp/build.gradle b/uploadservice-okhttp/build.gradle
index 381f6ec9..e92bab6b 100644
--- a/uploadservice-okhttp/build.gradle
+++ b/uploadservice-okhttp/build.gradle
@@ -69,7 +69,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- api 'com.squareup.okhttp3:okhttp:4.9.2'
+ api 'com.squareup.okhttp3:okhttp:4.10.0'
//api "net.gotev:uploadservice:${version}"
//comment the previous line and uncomment the next line for development (it uses the local lib)
api project(':uploadservice')
diff --git a/uploadservice/build.gradle b/uploadservice/build.gradle
index b7d8a326..e23a3962 100644
--- a/uploadservice/build.gradle
+++ b/uploadservice/build.gradle
@@ -22,9 +22,9 @@ version = library_version
android {
namespace "net.gotev.uploadservice"
- compileSdkVersion target_sdk
defaultConfig {
+ compileSdk target_sdk
minSdkVersion min_sdk
targetSdkVersion target_sdk
versionCode version_code
diff --git a/uploadservice/src/main/AndroidManifest.xml b/uploadservice/src/main/AndroidManifest.xml
index 61d63087..8e231691 100644
--- a/uploadservice/src/main/AndroidManifest.xml
+++ b/uploadservice/src/main/AndroidManifest.xml
@@ -5,13 +5,15 @@
+
+ android:exported="false" />
diff --git a/uploadservice/src/main/java/net/gotev/uploadservice/UploadService.kt b/uploadservice/src/main/java/net/gotev/uploadservice/UploadService.kt
index 130d1331..9c5bb907 100644
--- a/uploadservice/src/main/java/net/gotev/uploadservice/UploadService.kt
+++ b/uploadservice/src/main/java/net/gotev/uploadservice/UploadService.kt
@@ -4,6 +4,7 @@ import android.app.Notification
import android.app.Service
import android.content.Context
import android.content.Intent
+import android.os.Build
import android.os.IBinder
import android.os.PowerManager
import androidx.core.app.NotificationCompat
@@ -165,6 +166,15 @@ class UploadService : Service() {
return false
}
+ private fun stopServiceForeground() {
+ if (Build.VERSION.SDK_INT >= 24) {
+ stopForeground(STOP_FOREGROUND_REMOVE)
+ } else {
+ @Suppress("DEPRECATION")
+ stopForeground(true)
+ }
+ }
+
/**
* Called by each task when it is completed (either successfully, with an error or due to
* user cancellation).
@@ -182,7 +192,7 @@ class UploadService : Service() {
if (UploadServiceConfig.isForegroundService && uploadTasksMap.isEmpty()) {
UploadServiceLogger.debug(TAG, NA) { "All tasks completed, stopping foreground execution" }
- stopForeground(true)
+ stopServiceForeground()
shutdownIfThereArentAnyActiveTasks()
}
}
@@ -248,7 +258,7 @@ class UploadService : Service() {
if (UploadServiceConfig.isForegroundService) {
UploadServiceLogger.debug(TAG, NA) { "Stopping foreground execution" }
- stopForeground(true)
+ stopServiceForeground()
}
wakeLock.safeRelease()
diff --git a/uploadservice/src/main/java/net/gotev/uploadservice/data/BroadcastData.kt b/uploadservice/src/main/java/net/gotev/uploadservice/data/BroadcastData.kt
index cdfa049c..6b32ea82 100644
--- a/uploadservice/src/main/java/net/gotev/uploadservice/data/BroadcastData.kt
+++ b/uploadservice/src/main/java/net/gotev/uploadservice/data/BroadcastData.kt
@@ -4,6 +4,7 @@ import android.content.Intent
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import net.gotev.uploadservice.UploadServiceConfig
+import net.gotev.uploadservice.extensions.parcelableCompat
import net.gotev.uploadservice.network.ServerResponse
@Parcelize
@@ -17,7 +18,7 @@ internal data class BroadcastData @JvmOverloads constructor(
private const val paramName = "broadcastData"
fun fromIntent(intent: Intent): BroadcastData? {
- return intent.getParcelableExtra(paramName)
+ return intent.parcelableCompat(paramName)
}
}
diff --git a/uploadservice/src/main/java/net/gotev/uploadservice/extensions/ContextExtensions.kt b/uploadservice/src/main/java/net/gotev/uploadservice/extensions/ContextExtensions.kt
index 09e6f4eb..2f372cf4 100644
--- a/uploadservice/src/main/java/net/gotev/uploadservice/extensions/ContextExtensions.kt
+++ b/uploadservice/src/main/java/net/gotev/uploadservice/extensions/ContextExtensions.kt
@@ -1,9 +1,14 @@
package net.gotev.uploadservice.extensions
+import android.annotation.SuppressLint
import android.app.PendingIntent
+import android.content.BroadcastReceiver
import android.content.Context
+import android.content.Context.RECEIVER_NOT_EXPORTED
import android.content.Intent
-import android.os.Build
+import android.content.IntentFilter
+import android.os.Build.VERSION.SDK_INT
+import android.os.Parcelable
import net.gotev.uploadservice.UploadService
import net.gotev.uploadservice.UploadServiceConfig
import net.gotev.uploadservice.UploadTask
@@ -43,7 +48,7 @@ fun Context.startNewUpload(
*/
startService(intent)
} catch (exc: Throwable) {
- if (Build.VERSION.SDK_INT >= 26 && exc is IllegalStateException) {
+ if (SDK_INT >= 26 && exc is IllegalStateException) {
/*
this is a bugged Android API and Google is not going to fix it
@@ -79,7 +84,6 @@ data class UploadTaskCreationParameters(
val notificationConfig: UploadNotificationConfig
)
-@Suppress("UNCHECKED_CAST")
fun Intent?.getUploadTaskCreationParameters(): UploadTaskCreationParameters? {
if (this == null || action != UploadServiceConfig.uploadAction) {
UploadServiceLogger.error(
@@ -92,7 +96,7 @@ fun Intent?.getUploadTaskCreationParameters(): UploadTaskCreationParameters? {
return null
}
- val params: UploadTaskParameters = getParcelableExtra(taskParametersKey) ?: run {
+ val params: UploadTaskParameters = parcelableCompat(taskParametersKey) ?: run {
UploadServiceLogger.error(
component = UploadService.TAG,
uploadId = NA,
@@ -129,7 +133,7 @@ fun Intent?.getUploadTaskCreationParameters(): UploadTaskCreationParameters? {
}
val notificationConfig: UploadNotificationConfig =
- getParcelableExtra(taskNotificationConfig) ?: run {
+ parcelableCompat(taskNotificationConfig) ?: run {
UploadServiceLogger.error(
component = UploadService.TAG,
uploadId = NA,
@@ -148,7 +152,6 @@ fun Intent?.getUploadTaskCreationParameters(): UploadTaskCreationParameters? {
/**
* Creates a new task instance based on the requested task class in the intent.
- * @param intent intent passed to the service
* @return task instance or null if the task class is not supported or invalid
*/
@Suppress("UNCHECKED_CAST")
@@ -221,9 +224,23 @@ val Intent.uploadIdToCancel: String?
// Adjusts flags for Android 12+
fun flagsCompat(flags: Int): Int {
- if (Build.VERSION.SDK_INT > 30) {
+ if (SDK_INT > 30) {
return flags or PendingIntent.FLAG_IMMUTABLE
}
return flags
}
+
+inline fun Intent.parcelableCompat(key: String): T? = when {
+ SDK_INT >= 34 -> getParcelableExtra(key, T::class.java)
+ else -> @Suppress("DEPRECATION") getParcelableExtra(key) as? T
+}
+
+@SuppressLint("UnspecifiedRegisterReceiverFlag")
+fun Context.registerReceiverCompat(receiver: BroadcastReceiver, filter: IntentFilter) {
+ if (SDK_INT >= 34) {
+ registerReceiver(receiver, filter, RECEIVER_NOT_EXPORTED)
+ } else {
+ registerReceiver(receiver, filter)
+ }
+}
diff --git a/uploadservice/src/main/java/net/gotev/uploadservice/observer/request/BaseRequestObserver.kt b/uploadservice/src/main/java/net/gotev/uploadservice/observer/request/BaseRequestObserver.kt
index d65e1e31..7f5c120f 100644
--- a/uploadservice/src/main/java/net/gotev/uploadservice/observer/request/BaseRequestObserver.kt
+++ b/uploadservice/src/main/java/net/gotev/uploadservice/observer/request/BaseRequestObserver.kt
@@ -7,6 +7,7 @@ import net.gotev.uploadservice.UploadServiceConfig
import net.gotev.uploadservice.data.BroadcastData
import net.gotev.uploadservice.data.UploadInfo
import net.gotev.uploadservice.data.UploadStatus
+import net.gotev.uploadservice.extensions.registerReceiverCompat
open class BaseRequestObserver(
private val context: Context,
@@ -33,7 +34,7 @@ open class BaseRequestObserver(
}
open fun register() {
- context.registerReceiver(this, UploadServiceConfig.broadcastStatusIntentFilter)
+ context.registerReceiverCompat(this, UploadServiceConfig.broadcastStatusIntentFilter)
}
open fun unregister() {
diff --git a/uploadservice/src/main/java/net/gotev/uploadservice/observer/request/NotificationActionsObserver.kt b/uploadservice/src/main/java/net/gotev/uploadservice/observer/request/NotificationActionsObserver.kt
index b70c06b1..db25e5a2 100644
--- a/uploadservice/src/main/java/net/gotev/uploadservice/observer/request/NotificationActionsObserver.kt
+++ b/uploadservice/src/main/java/net/gotev/uploadservice/observer/request/NotificationActionsObserver.kt
@@ -6,6 +6,7 @@ import android.content.Intent
import net.gotev.uploadservice.UploadService
import net.gotev.uploadservice.UploadServiceConfig.broadcastNotificationAction
import net.gotev.uploadservice.UploadServiceConfig.broadcastNotificationActionIntentFilter
+import net.gotev.uploadservice.extensions.registerReceiverCompat
import net.gotev.uploadservice.extensions.uploadIdToCancel
import net.gotev.uploadservice.logger.UploadServiceLogger
import net.gotev.uploadservice.logger.UploadServiceLogger.NA
@@ -28,7 +29,7 @@ open class NotificationActionsObserver(
}
fun register() {
- context.registerReceiver(this, broadcastNotificationActionIntentFilter)
+ context.registerReceiverCompat(this, broadcastNotificationActionIntentFilter)
UploadServiceLogger.debug(NotificationActionsObserver::class.java.simpleName, NA) {
"registered"
}