Skip to content

Commit

Permalink
feat: Android API 33 support (gotev#639)
Browse files Browse the repository at this point in the history
* feat: updated all dependencies, gradle and bumped target SDK to 33

* feat: updated library manifest to include POST_NOTIFICATIONS permission and demo app to request notifications permissions on demand on android API 33+

* ci: bump java to 17 and API to 33

* readme: update for android 13

* feat: updated SimpleMultipartUpload demo app
  • Loading branch information
gotev committed Jul 9, 2023
1 parent 1f07a5a commit f2254d4
Show file tree
Hide file tree
Showing 30 changed files with 123 additions and 67 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/android.yml
Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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
4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -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 <a name="features"></a>
* 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.
Expand Down
30 changes: 19 additions & 11 deletions examples/SimpleMultipartUpload/app/build.gradle
Expand Up @@ -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"
}
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.gotev.testapp">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

<application
android:allowBackup="true"
Expand All @@ -10,7 +11,8 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
@@ -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() {
Expand All @@ -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<Button>(R.id.uploadButton).setOnClickListener {
pickFile()
Expand Down
11 changes: 9 additions & 2 deletions examples/SimpleMultipartUpload/build.gradle
@@ -1,13 +1,20 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.4.32'
ext.gradle_version = '8.0.2'
ext.kotlin_version = '1.8.20'
ext.target_sdk = 33

repositories {
google()
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.3'
classpath "com.android.tools.build:gradle:$gradle_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
2 changes: 1 addition & 1 deletion examples/app/.idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions examples/app/demoapp/build.gradle
Expand Up @@ -2,6 +2,7 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

android {
namespace "net.gotev.uploadservicedemo"
compileSdkVersion target_sdk

defaultConfig {
Expand Down Expand Up @@ -31,8 +32,8 @@ android {
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}

Expand Down
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
3 changes: 1 addition & 2 deletions examples/app/demoapp/src/main/AndroidManifest.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.gotev.uploadservicedemo">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application
android:name=".App"
Expand Down
@@ -1,12 +1,17 @@
package net.gotev.uploadservicedemo.activities

import android.Manifest
import android.app.PendingIntent
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import net.gotev.uploadservice.data.UploadNotificationAction
import net.gotev.uploadservice.data.UploadNotificationConfig
import net.gotev.uploadservice.data.UploadNotificationStatusConfig
Expand All @@ -19,6 +24,22 @@ import net.gotev.uploadservicedemo.extensions.inputMethodManager
import java.util.ArrayList

open class BaseActivity : AppCompatActivity() {

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)
checkPostNotificationsPermission()
}

override fun onPause() {
super.onPause()

Expand Down
1 change: 1 addition & 0 deletions examples/app/gradle.properties
Expand Up @@ -18,3 +18,4 @@
# org.gradle.parallel=true
android.enableJetifier=true
android.useAndroidX=true
android.defaults.buildfeatures.buildconfig=true
4 changes: 2 additions & 2 deletions examples/app/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Fri Aug 21 13:17:15 CEST 2020
#Sun Jul 09 10:09:56 CEST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
1 change: 1 addition & 0 deletions gradle.properties
Expand Up @@ -18,3 +18,4 @@
org.gradle.parallel=true
org.gradle.caching=true
android.useAndroidX=true
android.defaults.buildfeatures.buildconfig=true
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
28 changes: 14 additions & 14 deletions manifest.gradle
Expand Up @@ -9,29 +9,29 @@ ext {
library_licenses = ["Apache-2.0"]
library_licenses_url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
library_project_group = 'net.gotev'
library_version = '4.7.0'
version_code = 48
library_version = '4.8.0'
version_code = 49
min_sdk = 21
target_sdk = 31
target_sdk = 33
demo_app_id = 'net.gotev.uploadservicedemo'

// Gradle classpath dependencies versions
kotlin_version = '1.4.32'
gradle_version = '7.0.3'
kotlin_version = '1.8.20'
gradle_version = '8.0.2'
kotlin_lint_version = '9.0.0'

// Library and app testing dependencies versions
junit_version = '4.13'
androidx_test_core_version = '1.3.0'
androidx_test_runner_version = '1.3.0'
androidx_test_rules_version = '1.3.0'
androidx_test_ext_junit_version = '1.1.2'
androidx_test_ext_truth_version = '1.3.0'
junit_version = '4.13.2'
androidx_test_core_version = '1.5.0'
androidx_test_runner_version = '1.5.2'
androidx_test_rules_version = '1.5.0'
androidx_test_ext_junit_version = '1.1.5'
androidx_test_ext_truth_version = '1.5.0'
truth_version = '1.0.1'
androidx_test_espresso_version = '3.3.0'
androidx_test_espresso_version = '3.5.1'
mock_web_server_version = '4.9.0'

// Library and app dependencies versions
androidx_lifecycle_version = '2.3.1'
androidx_appcompat_version = '1.3.0'
androidx_lifecycle_version = '2.6.1'
androidx_appcompat_version = '1.6.1'
}
5 changes: 3 additions & 2 deletions uploadservice-ftp/build.gradle
Expand Up @@ -20,6 +20,7 @@ group = library_project_group
version = library_version

android {
namespace "net.gotev.uploadservice.ftp"
compileSdkVersion target_sdk

defaultConfig {
Expand All @@ -38,8 +39,8 @@ android {
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

lintOptions {
Expand Down
2 changes: 1 addition & 1 deletion uploadservice-ftp/gradle/wrapper/gradle-wrapper.properties
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
2 changes: 1 addition & 1 deletion uploadservice-ftp/src/main/AndroidManifest.xml
@@ -1,4 +1,4 @@
<manifest package="net.gotev.uploadservice.ftp">
<manifest>

<application></application>

Expand Down
5 changes: 3 additions & 2 deletions uploadservice-okhttp/build.gradle
Expand Up @@ -20,6 +20,7 @@ group = library_project_group
version = library_version

android {
namespace "net.gotev.uploadservice.okhttp"
compileSdkVersion target_sdk

defaultConfig {
Expand All @@ -38,8 +39,8 @@ android {
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

lintOptions {
Expand Down
2 changes: 1 addition & 1 deletion uploadservice-okhttp/src/main/AndroidManifest.xml
@@ -1,4 +1,4 @@
<manifest package="net.gotev.uploadservice.okhttp">
<manifest>

<application></application>

Expand Down

0 comments on commit f2254d4

Please sign in to comment.