Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# OneSignal Capacitor Plugin – Android

Thin Capacitor wrapper around the OneSignal Android SDK. Designed to be consumed as a Capacitor sub-project under both Capacitor 7 and Capacitor 8.

## Kotlin / AGP toolchain

The plugin module declares its own `buildscript` classpath for the Android Gradle Plugin and the Kotlin Gradle Plugin. This is required because Capacitor 7's host `build.gradle` does not classpath the Kotlin Gradle Plugin for sub-projects; without our own classpath the `kotlin-android` plugin would fail to resolve.

Defaults live in [`gradle/libs.versions.toml`](gradle/libs.versions.toml):

- `kotlin = "2.2.20"` – the compiler version used to build this module. Matches the Capacitor 8 upgrade guide's recommended `kotlin_version`, and a 2.2.x compiler reads `kotlin-stdlib` bytecode from both 1.x and 2.x, which is what makes a single artifact work on Capacitor 7 hosts (Kotlin 1.9.x stdlib) and Capacitor 8 hosts (Kotlin 2.2.x stdlib).
- `androidGradlePlugin = "8.7.3"` – intentionally stays below Capacitor 8's recommended 8.13.0 so plugin-only Gradle invocations still work from a freshly scaffolded Capacitor 7 project (Gradle 8.11.1). In host builds the host's AGP wins regardless.

Host apps that need to pin a different Kotlin compiler can do so via any standard Gradle property source — `rootProject.ext.kotlin_version` in their root `build.gradle`, `kotlin_version=…` in `gradle.properties`, or `-Pkotlin_version=…` on the command line. The plugin's buildscript block reads the value through `project.findProperty("kotlin_version")` and falls back to the catalog default.

## SDK levels

`compileSdk`, `minSdk`, and `targetSdk` default to the Capacitor 8 floors (36 / 24 / 36). Host apps override any of them by setting the matching `<name>Version` property through any Gradle property source (`rootProject.ext`, `gradle.properties`, or `-P`) — Capacitor 7 host apps that ship with `variables.gradle` defaults of 35 / 23 / 35 will continue to take precedence over the catalog defaults.

## Library versions

`androidx.appcompat`, `junit`, espresso, and the OneSignal native SDK versions also live in [`gradle/libs.versions.toml`](gradle/libs.versions.toml). `androidxAppCompatVersion` and `junitVersion` can be overridden per-project through any Gradle property source (`rootProject.ext`, `gradle.properties`, or `-P`).
39 changes: 23 additions & 16 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,23 @@ buildscript {
return result ?: error("Version '$key' not found in ${catalogFile.name}")
}

val kotlinVersion: String = if (project.hasProperty("kotlin_version")) {
rootProject.extra["kotlin_version"] as String
} else {
fromCatalog("kotlin")
}
// Both AGP and Kotlin Gradle Plugin are classpathed here so the plugin
// builds inside Capacitor 7 hosts, whose root build.gradle does not
// provide either for sub-projects. Capacitor 8 hosts that already pin
// their own kotlin_version can override via rootProject.ext.kotlin_version.
//
// The catalog default matches the Capacitor 8 upgrade guide's
// recommended kotlin_version (2.2.20). That matters because the host
// classpath can resolve kotlin-stdlib to 2.x; the 1.9 compiler can't
// read 2.x metadata, which is exactly what broke 1.0.2 on Capacitor 8
// (issue #18). A 2.2.x compiler reads both 1.x and 2.x stdlib bytecode,
// so the plugin works under Cap 7 and Cap 8.
// findProperty matches hasProperty's broad source set (extras, gradle.properties,
// -P flags, ORG_GRADLE_PROJECT_* env vars). Reading rootProject.extra directly
// would only see ext { ... } values and crash on the others with
// UnknownPropertyException, so prefer findProperty + toString().
val kotlinVersion: String =
project.findProperty("kotlin_version")?.toString() ?: fromCatalog("kotlin")
val androidGradlePluginVersion: String = fromCatalog("androidGradlePlugin")

repositories {
Expand Down Expand Up @@ -63,19 +75,14 @@ fun catalogVersion(key: String): String {
return result ?: error("Version '$key' not found in ${toml.name}")
}

// See the kotlin_version note in buildscript {}: findProperty honors every property
// source hasProperty does (extras, gradle.properties, -P, env), and toString()
// avoids the String/Int cast hazard since gradle.properties values are always String.
fun propertyOrCatalog(propertyName: String, catalogKey: String): String =
if (project.hasProperty(propertyName)) {
rootProject.extra[propertyName] as String
} else {
catalogVersion(catalogKey)
}
project.findProperty(propertyName)?.toString() ?: catalogVersion(catalogKey)

fun intPropertyOrCatalog(propertyName: String, catalogKey: String): Int =
if (project.hasProperty(propertyName)) {
rootProject.extra[propertyName] as Int
} else {
catalogVersion(catalogKey).toInt()
}
project.findProperty(propertyName)?.toString()?.toInt() ?: catalogVersion(catalogKey).toInt()

val junitVersion: String = propertyOrCatalog("junitVersion", "junit")
val androidxAppCompatVersion: String = propertyOrCatalog("androidxAppCompatVersion", "androidxAppCompat")
Expand Down Expand Up @@ -108,7 +115,7 @@ configure<com.android.build.gradle.LibraryExtension> {
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
kotlinOptions.jvmTarget = "17"
compilerOptions.jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)
}

repositories {
Expand Down
33 changes: 22 additions & 11 deletions android/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
# Version catalog for the OneSignal Capacitor Android plugin.
# Defaults below can be overridden by the consuming app via gradle
# properties or rootProject.extra (see android/build.gradle.kts).
#
# compileSdk / minSdk / targetSdk / kotlin / appcompat / junit follow
# Capacitor 7's required versions, not the OneSignal Android SDK's.
# Host apps can override most defaults by setting the matching
# rootProject.ext.<key> values; see android/build.gradle.kts for the
# property-or-catalog lookup logic.
#
# kotlin: matches Capacitor 8's recommended kotlin_version (2.2.20, per
# Capacitor 8 upgrade docs). A 2.2.x compiler reads kotlin-stdlib bytecode
# from 1.x and 2.x without metadata version errors, which is what makes a
# single artifact compile under both Capacitor 7 hosts (Kotlin 1.9.x
# stdlib) and Capacitor 8 hosts (Kotlin 2.2.x stdlib).
# androidGradlePlugin: kept at 8.7.3. Cap 8 recommends 8.13.0, but bumping
# here would force Gradle 8.13+ in standalone plugin builds, which a
# freshly scaffolded Cap 7 project (Gradle 8.11.1) cannot supply. In host
# builds the host's AGP wins regardless.
# SDK levels / library versions: bumped to Capacitor 8's recommended floors
# for documentation parity. Host apps still override via rootProject.ext.

[versions]
androidGradlePlugin = "8.7.3"
androidxAppCompat = "1.7.0"
androidxEspresso = "3.6.1"
androidxTestJunit = "1.2.1"
compileSdk = "35"
androidxAppCompat = "1.7.1"
androidxEspresso = "3.7.0"
androidxTestJunit = "1.3.0"
compileSdk = "36"
junit = "4.13.2"
kotlin = "1.9.25"
minSdk = "23"
kotlin = "2.2.20"
minSdk = "24"
onesignal = "5.9.1"
targetSdk = "35"
targetSdk = "36"

[libraries]
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidxAppCompat" }
Expand Down
3 changes: 3 additions & 0 deletions examples/demo_cap7/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Angular CLI cache + intermediate TS output
.angular/
out-tsc/
45 changes: 45 additions & 0 deletions examples/demo_cap7/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# demo-cap7

Minimal Capacitor 7 + Angular sample used to verify the OneSignal Capacitor plugin against the older Kotlin / AGP toolchain that Capacitor 7 ships with. Pairs with `examples/demo` (Capacitor 8, Ionic React).

## Stack

- Capacitor 7 (`@capacitor/core` `^7.4.3`)
- Angular 18 standalone components, bootstrapped with `bootstrapApplication`
- Angular CLI (`ng build` / `ng serve`) – no Ionic, no extra build tooling
- Single root component with four buttons and a signal-backed log

## What the demo does

1. Initialize OneSignal
2. Request notification permission
3. Show the OneSignal user / push subscription id (paste it into the OneSignal dashboard to send a test push)
4. Send Test Notification – POSTs `{ headings: 'Simple Notification', contents: 'This is a simple push notification' }` to the OneSignal REST API (`v1/notifications`) targeting the current push subscription id. Mirrors the Simple notification button in `examples/demo`; no REST API key needed since the call targets the device's own subscription id.

## First-time setup

The `android/` and `ios/` projects are committed (scaffolded via Capacitor 7's CLI, AGP 8.7.x, no root Kotlin Gradle Plugin classpath), so the only setup is dependencies and the plugin tarball.

```bash
# from the repo root: build + pack the plugin tarball
vp run build
vp pm pack && mv onesignal-capacitor-plugin-*.tgz onesignal-capacitor-plugin.tgz

# in this folder: install deps and the local plugin tarball
cd examples/demo_cap7
bun install
```

The OneSignal plugin module compiles against the Kotlin 2.2.20 compiler it ships in its own buildscript classpath, which reads both 1.x and 2.x `kotlin-stdlib` bytecode.

`ONESIGNAL_APP_ID` in `src/app/app.component.ts` defaults to the shared OneSignal demo app id (same one used by `examples/demo`). Swap it for your own app id before pointing the demo at a production environment.

## Running

```bash
bun run build # ng build → dist/browser
bunx cap sync # copy web + plugin into native projects
bunx cap run android # or: bunx cap run ios
```

The Angular CLI builder emits to `dist/browser/`; `capacitor.config.ts` points `webDir` there.
101 changes: 101 additions & 0 deletions examples/demo_cap7/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore

# Built application files
*.apk
*.aar
*.ap_
*.aab

# Files for the ART/Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/
# Uncomment the following line in case you need and you don't have the release build type files in your app
# release/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
# Android Studio 3 in .gitignore file.
.idea/caches
.idea/modules.xml
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
.idea/navEditor.xml

# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore

# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
.cxx/

# Google Services (e.g. APIs or Firebase)
# google-services.json

# Freeline
freeline.py
freeline/
freeline_project_description.json

# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md

# Version control
vcs.xml

# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/

# Android Profiling
*.hprof

# Cordova plugins for Capacitor
capacitor-cordova-android-plugins

# Copied web assets
app/src/main/assets/public

# Generated Config files
app/src/main/assets/capacitor.config.json
app/src/main/assets/capacitor.plugins.json
app/src/main/res/xml/config.xml
2 changes: 2 additions & 0 deletions examples/demo_cap7/android/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build/*
!/build/.npmkeep
54 changes: 54 additions & 0 deletions examples/demo_cap7/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
apply plugin: 'com.android.application'

android {
namespace "com.onesignal.example"
compileSdk rootProject.ext.compileSdkVersion
defaultConfig {
applicationId "com.onesignal.example"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
// Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

repositories {
flatDir{
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
}
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
implementation project(':capacitor-android')
testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
implementation project(':capacitor-cordova-android-plugins')
}

apply from: 'capacitor.build.gradle'

try {
def servicesJSON = file('google-services.json')
if (servicesJSON.text) {
apply plugin: 'com.google.gms.google-services'
}
} catch(Exception e) {
logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
}
21 changes: 21 additions & 0 deletions examples/demo_cap7/android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Loading
Loading