Skip to content

Commit

Permalink
fix(Android): Fix crash when targeting SDK 31+ (#165)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `targetSdkVersion` is now required to be 31+ for Android users.
  • Loading branch information
Rapsssito committed Dec 21, 2022
1 parent 009a424 commit c70554e
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 50 deletions.
49 changes: 29 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ React Native background service library for running **background tasks forever i

## Table of Contents <!-- omit in toc -->

- [React Native / Android / iOS compatibility](#react-native--android--ios-compatibility)
- [Install](#install)
- [Usage](#usage)
- [Example Code](#example-code)
Expand All @@ -29,6 +30,14 @@ React Native background service library for running **background tasks forever i
- [Acknowledgments](#acknowledgments)
- [License](#license)

## React Native / Android / iOS compatibility
To use this module you need to ensure you are using the correct version of React Native. If you are using an Android (targetSdkVersion) version lower than 31 (introduced in React Native 0.68.0) you will need to upgrade before attempting to use `react-native-background-actions`'s latest version.

| Version | React Native version | Android (targetSdkVersion) version | iOS version |
| ------- | -------------------- | ---------------------------------- | ------------ |
| `3.X.X` | `>= Unknown` | `>= 31` | `>= Unknown` |
| `2.6.7` | `>= Unknown` | `>= Unknown` | `>= Unknown` |

## Install

Go to [INSTALL.md](./INSTALL.md) to see the how to install, compatibility with RN and Linking process.
Expand Down Expand Up @@ -83,36 +92,36 @@ await BackgroundService.stop();
> If .start() is called on the backgound, it will not have any effect.
### Options
| Property | Type | Description |
| ----------- | ---------- | ------------------------------------------------ |
| `taskName` | `<string>` | Task name for identification. |
| `taskTitle` | `<string>` | **Android Required**. Notification title. |
| `taskDesc` | `<string>` | **Android Required**. Notification description. |
| `taskIcon` | [`<taskIconOptions>`](#taskIconOptions) | **Android Required**. Notification icon. |
| `color` | `<string>` | Notification color. **Default**: `"#ffffff"`. |
| `linkingURI` | `<string>` | Link that will be called when the notification is clicked. Example: `"yourSchemeHere://chat/jane"`. See [Deep Linking](#deep-linking) for more info. **Default**: `undefined`. |
| `progressBar` | [`<taskProgressBarOptions>`](#taskProgressBarOptions) | Notification progress bar. |
| `parameters` | `<any>` | Parameters to pass to the task. |
| Property | Type | Description |
| ------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `taskName` | `<string>` | Task name for identification. |
| `taskTitle` | `<string>` | **Android Required**. Notification title. |
| `taskDesc` | `<string>` | **Android Required**. Notification description. |
| `taskIcon` | [`<taskIconOptions>`](#taskIconOptions) | **Android Required**. Notification icon. |
| `color` | `<string>` | Notification color. **Default**: `"#ffffff"`. |
| `linkingURI` | `<string>` | Link that will be called when the notification is clicked. Example: `"yourSchemeHere://chat/jane"`. See [Deep Linking](#deep-linking) for more info. **Default**: `undefined`. |
| `progressBar` | [`<taskProgressBarOptions>`](#taskProgressBarOptions) | Notification progress bar. |
| `parameters` | `<any>` | Parameters to pass to the task. |

#### taskIconOptions
**Android only**
| Property | Type | Description |
| ----------- | ---------- | -------------------------------------------------------------- |
| `name` | `<string>` | **Required**. Icon name in res/ folder. Ex: `ic_launcher`. |
| `type` | `<string>` | **Required**. Icon type in res/ folder. Ex: `mipmap`. |
| `package` | `<string>` | Icon package where to search the icon. Ex: `com.example.package`. **It defaults to the app's package. It is highly recommended to leave like that.** |
| Property | Type | Description |
| --------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name` | `<string>` | **Required**. Icon name in res/ folder. Ex: `ic_launcher`. |
| `type` | `<string>` | **Required**. Icon type in res/ folder. Ex: `mipmap`. |
| `package` | `<string>` | Icon package where to search the icon. Ex: `com.example.package`. **It defaults to the app's package. It is highly recommended to leave like that.** |

Example:

![photo5837026843969041365](https://user-images.githubusercontent.com/44206249/72532521-de49e280-3873-11ea-8bf6-00618bcb82ab.jpg)

#### taskProgressBarOptions
**Android only**
| Property | Type | Description |
| ----------- | ---------- | -------------------------------------------------------------- |
| `max` | `<number>` | **Required**. Maximum value. |
| `value` | `<number>` | **Required**. Current value. |
| `indeterminate` | `<boolean>` | Display the progress status as indeterminate. |
| Property | Type | Description |
| --------------- | ----------- | --------------------------------------------- |
| `max` | `<number>` | **Required**. Maximum value. |
| `value` | `<number>` | **Required**. Current value. |
| `indeterminate` | `<boolean>` | Display the progress status as indeterminate. |

Example:

Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ def safeExtGet(prop, fallback) {
}

android {
compileSdkVersion safeExtGet('compileSdkVersion', 28)
compileSdkVersion safeExtGet('compileSdkVersion', 31)

defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', 16)
targetSdkVersion safeExtGet('targetSdkVersion', 28)
targetSdkVersion safeExtGet('targetSdkVersion', 31)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.asterinet.react.bgactions;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
Expand All @@ -23,6 +24,7 @@ final public class RNBackgroundActionsTask extends HeadlessJsTaskService {
public static final int SERVICE_NOTIFICATION_ID = 92901;
private static final String CHANNEL_ID = "RN_BACKGROUND_ACTIONS_CHANNEL";

@SuppressLint("UnspecifiedImmutableFlag")
@NonNull
public static Notification buildNotification(@NonNull Context context, @NonNull final BackgroundTaskOptions bgOptions) {
// Get info
Expand All @@ -39,8 +41,10 @@ public static Notification buildNotification(@NonNull Context context, @NonNull
notificationIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
}
final PendingIntent contentIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_MUTABLE);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
} else {
contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Expand Down
7 changes: 3 additions & 4 deletions examples/backgroundExample/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ buildscript {
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 28
compileSdkVersion = 31
targetSdkVersion = 31
}
repositories {
google()
jcenter()
}
dependencies {
classpath('com.android.tools.build:gradle:3.5.2')

classpath("com.android.tools.build:gradle:3.5.3")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
Expand Down
7 changes: 7 additions & 0 deletions examples/backgroundExample/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,12 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true

# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.37.0
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
35 changes: 15 additions & 20 deletions examples/backgroundExample/android/gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
Expand Down Expand Up @@ -125,8 +125,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
Expand Down Expand Up @@ -154,19 +154,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi

Expand All @@ -175,14 +175,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`

# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi

exec "$JAVACMD" "$@"
5 changes: 4 additions & 1 deletion examples/backgroundExample/android/gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
Expand All @@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

Expand Down

0 comments on commit c70554e

Please sign in to comment.