diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index b72ca9f4..988fdfe3 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -18,7 +18,7 @@ jobs: - name: run tests uses: reactivecircus/android-emulator-runner@v2 with: - api-level: 31 + api-level: 33 script: ./gradlew connectedCheck unit-test-and-build: @@ -29,7 +29,7 @@ jobs: - name: set up JDK uses: actions/setup-java@v1 with: - java-version: 11 + java-version: 17 - name: Unit Test run: ./gradlew testDebugUnitTest - name: Android Test Report @@ -46,6 +46,6 @@ jobs: - name: set up JDK uses: actions/setup-java@v1 with: - java-version: 11 + java-version: 17 - name: Build with Gradle run: cd examples/app && ./gradlew clean assembleDebug diff --git a/README.md b/README.md index aefbd8fd..7f26ccf5 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,9 @@ 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 12 (API 31) support. +* Android 5.0 (API 21) to Android 13 (API 33) 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*: * What's supported: uploads initiated while the app is in foreground, with progress indication notification * What's NOT supported: uploads started while the app is in the background or uploads without progress indication notification. This is due to the Service limitations imposed by Google, which requires all background services to display a notification to the user. Current architecture cannot support this. For support of those use-cases, WorkManager is the only option. diff --git a/examples/SimpleMultipartUpload/app/build.gradle b/examples/SimpleMultipartUpload/app/build.gradle index 9fde6c45..e8d152ff 100644 --- a/examples/SimpleMultipartUpload/app/build.gradle +++ b/examples/SimpleMultipartUpload/app/build.gradle @@ -2,34 +2,42 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { - compileSdkVersion 30 + namespace "it.gotev.testapp" + compileSdkVersion target_sdk + defaultConfig { applicationId "it.gotev.testapp" minSdkVersion 21 - targetSdkVersion 30 - versionCode 2 - versionName "1.1" + targetSdkVersion target_sdk + versionCode 3 + versionName "1.3" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.appcompat:appcompat:1.3.0' - implementation 'androidx.core:core-ktx:1.5.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' - testImplementation 'junit:junit:4.13' - androidTestImplementation 'androidx.test.ext:junit:1.1.2' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'androidx.core:core-ktx:1.10.1' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - def uploadServiceVersion = "4.5.5" + def uploadServiceVersion = "4.7.0" implementation "net.gotev:uploadservice:$uploadServiceVersion" } diff --git a/examples/SimpleMultipartUpload/app/src/main/AndroidManifest.xml b/examples/SimpleMultipartUpload/app/src/main/AndroidManifest.xml index f9ec4c43..685f4343 100644 --- a/examples/SimpleMultipartUpload/app/src/main/AndroidManifest.xml +++ b/examples/SimpleMultipartUpload/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ - + + + - + diff --git a/examples/SimpleMultipartUpload/app/src/main/java/it/gotev/testapp/MainActivity.kt b/examples/SimpleMultipartUpload/app/src/main/java/it/gotev/testapp/MainActivity.kt index f7f0f27b..963fdc7c 100644 --- a/examples/SimpleMultipartUpload/app/src/main/java/it/gotev/testapp/MainActivity.kt +++ b/examples/SimpleMultipartUpload/app/src/main/java/it/gotev/testapp/MainActivity.kt @@ -1,10 +1,15 @@ package it.gotev.testapp +import android.Manifest import android.app.Activity import android.content.Intent +import android.content.pm.PackageManager +import android.os.Build import android.os.Bundle import android.widget.Button +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat import net.gotev.uploadservice.protocols.multipart.MultipartUploadRequest class MainActivity : AppCompatActivity() { @@ -15,9 +20,20 @@ class MainActivity : AppCompatActivity() { const val pickFileRequestCode = 42 } + private val notificationPermissionRequest = registerForActivityResult(ActivityResultContracts.RequestPermission()) { + // custom logic when the user either allows or disallows notifications + } + + private fun checkPostNotificationsPermission() { + if (Build.VERSION.SDK_INT >= 33 && ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { + notificationPermissionRequest.launch(Manifest.permission.POST_NOTIFICATIONS) + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + checkPostNotificationsPermission() findViewById