Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.10.0; multiple Android and iOS fixes #2000

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ccad06f
iOS: Do not remove active alarms when rescheduling
timkellypa Jan 6, 2021
6576b38
Merge branch 'android-10-updates'
timkellypa Jan 30, 2021
083ccca
Persist base date within trigger.
timkellypa Aug 5, 2020
8a2f0c7
added 'PendingIntent.FLAG_MUTABLE' for API >= 31 to Notification.java
fquirin Jul 17, 2022
7d81d24
Added 'PendingIntent.FLAG_MUTABLE' for API >= 31 to Builder.java
fquirin Jul 17, 2022
9a5c4a9
replaced 'compile' with 'implementation' in gradle file and...
fquirin Jul 17, 2022
00c8228
Fixed import in Notification.java
fquirin Jul 29, 2022
953adb3
Cleaned-up Builder.java
fquirin Jul 29, 2022
c1696bd
Delete .DS_Store
fquirin Nov 18, 2022
6bcacac
prepare for v0.10.0
fquirin Nov 18, 2022
69faa3a
merged iOS changes by @bhandaribhumin
fquirin Nov 18, 2022
d6fcc37
Android: added 'setDummyNotifications' + smaller fixes (@bhandaribhumin)
fquirin Nov 18, 2022
db99ddd
Android: fix for click handling in Android 12 + code refactoring (@po…
fquirin Nov 18, 2022
de99069
updated plugin.xml to match new Android code
fquirin Nov 18, 2022
3bc3f0d
updated changelog and readme for this fork
fquirin Nov 18, 2022
c194111
Update local-notification.js
fquirin Nov 19, 2022
a3b5d5f
Update README.md
fquirin Nov 19, 2022
2832b96
restore compatibility with original repo
fquirin Dec 27, 2022
0275c59
Update README.md
fquirin Dec 27, 2022
f618d3a
fixed contributer name
fquirin Dec 27, 2022
3f3fb30
cleaned up code and added 'options' to 'setDummyNotifications'
fquirin Mar 19, 2023
93ffd5a
v0.10.1; updated version and changelog
fquirin Mar 19, 2023
c2ee2d1
Merge branch 'master' into pr-katzer
fquirin Mar 19, 2023
8a67e65
Merge branch 'master' into pr-katzer
fquirin Mar 19, 2023
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
Binary file removed .DS_Store
Binary file not shown.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
ChangeLog
---------

#### Version 0.10.0
- Fixed Android 12 bug to make notifications clickable (@powowbox) by replacing the action handler services with activities (avoid notification trampoline restrictions)
- Merged forks of @timkellypa and @bhandaribhumin (cordova-plugin-local-notification-12) back into original fork
- Android code clean-up and refactoring (@powowbox, @fquirin)
- Removed 'beta' from version name ... everything about Android/Cordova is 'beta' anyway ;-)

#### Version 0.9.0-beta.5 (from cordova-plugin-local-notification-12 by @bhandaribhumin)
- Fixed bugs 🐛
- Added missing 'PendingIntent.FLAG_MUTABLE' and fixed gradle
- Guard against webview crash
- Add thread identifier property
- Delete Alarms when intent is deleted
- Not calling delegate events if nil or if we're consuming the notification
- Android 13 `POST_NOTIFICATIONS ` permission and runtime popup added
- New interfaces to ask for / register permissions required to schedule local notifications
- New method addded for android `setDummyNotification()`

#### Version 0.9.0-beta.4
- Platform enhancements
- Android 8-10 device support
Expand Down Expand Up @@ -39,6 +56,7 @@ ChangeLog
- New `channelId` attribute. If passed in, a notification channel will be created (using volume and vibration settings to determine importance)
- Android: Support for excluding an application from battery optimization settings.
- Android: Support for allowing an application permissions to override Do Not Disturb.
- iOS: No longer remove notification from notification bar when alarms are rescheduled. Call cancel() explicitly to retain this behavior.

---

Expand Down Expand Up @@ -142,3 +160,8 @@ Please also read the [Upgrade Guide](https://github.com/katzer/cordova-plugin-lo
- Scheduling local notifications with the deprecated properties is still possible
- [Kitchen Sink sample app](https://github.com/katzer/cordova-plugin-local-notifications/tree/example)
- [Wiki](https://github.com/katzer/cordova-plugin-local-notifications/wiki)


### Version 0.8.0 (05.03.2015)

Added condition to get view from view or engine [PR](https://github.com/katzer/cordova-plugin-local-notifications/pull/1)
48 changes: 32 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@

<p align="left"><b><a href="https://github.com/katzer/cordova-plugin-local-notifications/tree/example-x">SAMPLE APP</a> :point_right:</b></p>

<br>

<p align="center">
<img src="images/logo.png">
</p>

<p align="center">
<a href="https://www.npmjs.com/package/cordova-plugin-local-notification">
<img src="https://badge.fury.io/js/cordova-plugin-local-notification.svg" alt="npm version" />
Expand All @@ -18,13 +15,10 @@
<img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License" />
</a>
</p>

<br>

> A notification is a message you display to the user outside of your app's normal UI. When you tell the system to issue a notification, it first appears as an icon in the notification area. To see the details of the notification, the user opens the notification drawer. Both the notification area and the notification drawer are system-controlled areas that the user can view at any time.

<br>

<img width="60%" align="right" hspace="19" vspace="12" src="https://storage.googleapis.com/material-design/publish/material_v_12/assets/0BwJzNNZmsTcKZy1YYTV3VWQzVUE/notifications-behavior-03-drawer.png"></img>
<img width="60%" align="right" hspace="19" vspace="12" src="https://storage.googleapis.com/material-design/publish/material_v_12/assets/0Bzhp5Z4wHba3S1JWc3NkTVpjVk0/notifications-guidelines-03-optin.png"></img>

Expand Down Expand Up @@ -53,17 +47,27 @@

## Important Notice

Please make sure that you always read the tagged README for the version you're using.
Please make sure that you always read the tagged README for the version you're using.

Latest v0.10.0 is a merge of [@timkellypa](https://github.com/timkellypa/cordova-plugin-local-notifications), [@bhandaribhumin](https://github.com/bhandaribhumin/cordova-plugin-local-notification-12) (with changes by [@powowbox](https://github.com/powowbox)) and [@fquirin](https://github.com/fquirin/cordova-plugin-local-notifications).
You can check out these repositories or the [PR section](https://github.com/katzer/cordova-plugin-local-notifications/pulls) for most recent fixes.

See the _0.8_ branch if you cannot upgrade. The `0.9-dev` and `ios10` branches are obsolete and will be removed soon.

See the _0.8_ branch if you cannot upgrade. Further development for `v0.9-beta` will happen here. The `0.9-dev` and `ios10` branches are obsolate and will be removed soon.
### Known issues and notes

__Known issues__
#### Android

- Support for Android Oreo is limited yet.
- v0.9 and v0.8 aren't compatible with each other (Wont fix)
- If the app is in background, it **must not** be launched but put in foreground.
- **Manual fix:** To avoid launching the app in this case, add the following in your config.xml file for Android `<preference name="AndroidLaunchMode" value="singleInstance"/>`
- If the app's in background and the 'triggerInApp' option is set to 'true', there is no way to show to users a new notification since the notification is not displayed in the notification center and the app is not visible.
- Implemented fix: If the app's running in background, display the notification in the notification center.
- If the notification is scheduled / canceled / scheduled with the same id, the notification triggers twice due to the random 'reqCode'.
- Implemented fix: Use the notification id for the 'reqCode'.

Please report bugs or missing features!
#### Other

- v0.9 and v0.8 aren't compatible with each other (Wont fix)

## Basics

Expand Down Expand Up @@ -96,7 +100,7 @@ A notification does have a set of configurable properties. Not all of them are s

| Property | Property | Property | Property | Property | Property | Property | Property | Property |
| :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ |
| id | data | timeoutAfter | summary | led | clock | channelName | actions | alarmVolume |
| id | data | timeoutAfter | summary | led | clock | channelName | actions | alarmVolume |
| text | icon | attachments | smallIcon | color | defaults | launch | groupSummary | resetDelay |
| title | silent | progressBar | sticky | vibrate | priority | mediaSession | foreground | autoLaunch |
| sound | trigger | group | autoClear | lockscreen | number | badge | wakeup | channelId |
Expand Down Expand Up @@ -451,7 +455,12 @@ cordova.plugins.notification.local.requestIgnoreBatteryOptimizations(function (g
```

The request method here will work one of two ways.
1. If you have the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission defined in the manifest, it will use ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS to explicitly ignore battery optimizations for this app. This is the best overall user experience, but the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission seems to be frowned upon and can get your app banned. This plugin does not have this permission in plugin.xml for this reason, so you will need to use the cordova-custom-config plugin to add it to your config.xml
1. If you have the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission defined in the manifest, it will use ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS to explicitly ignore battery optimizations for this app. This is the best overall user experience, but the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission seems to be frowned upon and can get your app banned. This plugin does not have this permission in plugin.xml for this reason, so you will need to use the cordova-custom-config plugin to add it to your config.xml. Alternatively, you can use the edit-config tag in the platform section of the config.xml.
```xml
<edit-config file="AndroidManifest.xml" mode="merge" target="/manifest/uses-permission" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
</edit-config>
```
2. If you do not have REQUEST_IGNORE_BATTERY_OPTIMIZATIONS requested, it will launch ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS to show a list of all applications. You will want to put some sort of instructions prior to this to walk the user through this. Also, this action doesn't exist on all Android devices (is missing on Samsung phones), which will make this method simply return false if it can't start the activity.


Expand Down Expand Up @@ -536,6 +545,13 @@ See the sample app for how to use them.
| clearAll | isPresent | getScheduledIds | getTriggered | setDefaults | hasDoNotDisturbPermissions |
| cancel | isScheduled | getTriggeredIds | addActions | on |

## SetDummyNotification

This method allows user to trigger runtime permission for Android 13

```js
cordova.plugins.notification.local.setDummyNotifications();
```

## Installation

Expand All @@ -549,9 +565,9 @@ Or install a specific version:

$ cordova plugin add cordova-plugin-local-notification@VERSION

Or install the latest head version:
Or install **a fork**:

$ cordova plugin add https://github.com/katzer/cordova-plugin-local-notifications.git
$ cordova plugin add https://github.com/fquirin/cordova-plugin-local-notifications.git

Or install from local source:

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-local-notification",
"version": "0.9.0-beta.4",
"version": "0.10.0",
"description": "Schedules and queries for local notifications",
"cordova": {
"id": "cordova-plugin-local-notification",
Expand Down Expand Up @@ -46,7 +46,7 @@
"version": ">=10.0.0"
}
],
"author": "Sebastián Katzer",
"author": "Sebastián Katzer, fquirin, Bhumin Bhandari, powowbox and more",
"license": "Apache 2.0",
"bugs": {
"url": "https://github.com/katzer/cordova-plugin-local-notifications/issues"
Expand Down
34 changes: 23 additions & 11 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* Apache 2.0 License
*
* Copyright (c) Sebastian Katzer 2017
* Contributors Bhumin Bhandari, fquirin, powowbox and many more:
* https://github.com/katzer/cordova-plugin-local-notifications/graphs/contributors
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
Expand All @@ -24,7 +26,7 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="cordova-plugin-local-notification"
version="0.9.0-beta.4">
version="0.10.0">

<name>LocalNotification</name>

Expand All @@ -36,21 +38,19 @@

<license>Apache 2.0</license>

<author>Sebastián Katzer</author>
<author>Sebastián Katzer, fquirin, Bhumin Bhandari, powowbox and more</author>

<!-- cordova -->
<engines>
<engine name="cordova" version=">=7.1.0" />
<engine name="cordova-plugman" version=">=4.3.0" />
<engine name="cordova-android" version=">=6.3.0" />
<engine name="cordova-windows" version=">=4.2.0" />
<!-- <engine name="android-sdk" version=">=26" /> -->
<engine name="apple-ios" version=">=10.0.0" />
<engine name="cordova" version=">=9.0.0"/>
<engine name="cordova-android" version=">=9.0.0"/>
<engine name="cordova-ios" version=">=6.0.0"/>
<engine name="cordova-windows" version=">=4.2.0"/>
</engines>

<!-- dependencies -->
<dependency id="cordova-plugin-device" />
<dependency id="cordova-plugin-badge" version=">=0.8.5" />
<dependency id="cordova-plugin-badge-fix" version=">=0.8.10"/><!-- TODO: return to 'cordova-plugin-badge' when fixed -->
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a reminder: it points to 'cordova-plugin-badge-fix' for the time being


<!-- js -->
<js-module src="www/local-notification.js" name="LocalNotification">
Expand Down Expand Up @@ -93,6 +93,11 @@
<preference name="ANDROID_SUPPORT_V4_VERSION" default="26.+" />
<framework src="com.android.support:support-v4:$ANDROID_SUPPORT_V4_VERSION" />
<framework src="src/android/build/localnotification.gradle" custom="true" type="gradleReference"/>
<!-- android x -->
<preference name="ANDROIDX_VERSION" default="1.2.0" />
<preference name="ANDROIDX_APPCOMPAT_VERSION" default="1.3.1" />

<framework src="androidx.appcompat:appcompat:$ANDROIDX_APPCOMPAT_VERSION" />

<config-file target="res/xml/config.xml" parent="/*">
<feature name="LocalNotification">
Expand All @@ -119,9 +124,10 @@
android:name="de.appplant.cordova.plugin.localnotification.ClearReceiver"
android:exported="false" />

<service
<activity
android:name="de.appplant.cordova.plugin.localnotification.ClickReceiver"
android:exported="false" />
android:exported="false"
android:theme="@style/Theme.AppCompat.NoActionBar"/>

<receiver
android:name="de.appplant.cordova.plugin.localnotification.RestoreReceiver"
Expand All @@ -138,6 +144,8 @@
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Schedule exact alarm is no longer allowed on android 13 for non alarm apps. https://developer.android.com/about/versions/14/changes/schedule-exact-alarms#calendar-alarm-clock)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have do it in a separate PR.
@fquirin What do you think?

</config-file>

<source-file
Expand Down Expand Up @@ -192,6 +200,10 @@
src="src/android/notification/receiver/AbstractTriggerReceiver.java"
target-dir="src/de/appplant/cordova/plugin/notification/receiver" />

<source-file
src="src/android/notification/receiver/NotificationTrampolineActivity.java"
target-dir="src/de/appplant/cordova/plugin/notification/receiver" />

<source-file
src="src/android/notification/trigger/DateTrigger.java"
target-dir="src/de/appplant/cordova/plugin/notification/trigger" />
Expand Down
55 changes: 53 additions & 2 deletions src/android/LocalNotification.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Apache 2.0 License
*
* Copyright (c) Sebastian Katzer 2017
* Contributor Bhumin Bhandari
fquirin marked this conversation as resolved.
Show resolved Hide resolved
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
Expand Down Expand Up @@ -40,6 +41,12 @@
import android.util.Pair;
import android.view.View;

import android.app.NotificationManager;
import android.app.NotificationChannel;
import android.app.PendingIntent;
import androidx.core.app.NotificationCompat;
import android.content.Intent;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
Expand Down Expand Up @@ -185,13 +192,52 @@ public void run() {
isIgnoringBatteryOptimizations(command);
} else if (action.equals("requestIgnoreBatteryOptimizations")) {
requestIgnoreBatteryOptimizations(command);
} else if (action.equals("dummyNotifications")) {
dummyNotifications(command);
}
}
});

return true;
}

/**
* Required for Android 13 to get the runtime notification permissions.
*
* @param command The callback context used when calling back into JavaScript.
*/
private void dummyNotifications(CallbackContext command) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is just creating a channel and should be renamed to reflect this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it is not optimal, though I'd prefer to merge this first before revisiting the purpose of this function


fireEvent("dummyNotifications");
NotificationManager mNotificationManager;
NotificationCompat.Builder mBuilder;
String NOTIFICATION_CHANNEL_ID = "10004457";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this channel-Id? It should be configurable.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It uses 'channeId' now from custom or default options. Only if this is not defined it falls back to the old ID (I have no idea why this ID was chosen by the other contributer).

String notificationMsg = "Test";
String notificationTitle = "Mdd";
fquirin marked this conversation as resolved.
Show resolved Hide resolved
Context context = cordova.getActivity().getApplicationContext();

Intent intentToLaunch = new Intent(context, TriggerReceiver.class);
intentToLaunch.putExtra("Callfrom", "reminders");

final PendingIntent resultPendingIntent = PendingIntent.getActivity(context,
0, intentToLaunch, PendingIntent.FLAG_IMMUTABLE);

mBuilder = new NotificationCompat.Builder(context,NOTIFICATION_CHANNEL_ID);
mBuilder.setContentIntent(resultPendingIntent);

mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method has only an effect on android >= 8. The code above should be moved in this if-statement, because it has no effect, if the if-statement is not executed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved it inside the if-case

int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is creating a Channel with the name "NOTIFICATION_CHANNEL_NAME" in Android >= 8. The channel name should be configurable or should use the same logic as creating a normal notification.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Method Options.getChannel is doing, what we need.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be fixed now, because I've added a new argument for 'options' (merged with plugin default options)

assert mNotificationManager != null;
mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
mNotificationManager.createNotificationChannel(notificationChannel);
}

command.success();
}

/**
* Determine if do not disturb permissions have been granted
*
Expand Down Expand Up @@ -701,7 +747,7 @@ static void fireEvent(String event, Notification toast, JSONObject data) {
sendJavascript(js);
}

/**
/**
* Use this instead of deprecated sendJavascript
*
* @param js JS code snippet as string.
Expand All @@ -713,12 +759,17 @@ private static synchronized void sendJavascript(final String js) {
return;
}

if (!deviceready || webView == null) {
eventQueue.add(js);
return;
}

final CordovaWebView view = webView.get();

((Activity) (view.getContext())).runOnUiThread(new Runnable() {
public void run() {
view.loadUrl("javascript:" + js);
View engineView = view.getEngine().getView();
View engineView = view.getEngine() != null ? view.getEngine().getView() : view.getView();

if (!isInForeground()) {
engineView.dispatchWindowVisibilityChanged(View.VISIBLE);
Expand Down
7 changes: 5 additions & 2 deletions src/android/TriggerReceiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,11 @@ public boolean checkAppRunning() {
*/
@Override
public Notification buildNotification(Builder builder, Bundle bundle) {
return builder.setClickActivity(ClickReceiver.class).setClearReceiver(ClearReceiver.class).setExtras(bundle)
.build();
return builder
.setClickActivity(ClickReceiver.class)
.setClearReceiver(ClearReceiver.class)
.setExtras(bundle)
.build();
}

}
4 changes: 2 additions & 2 deletions src/android/build/localnotification.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ repositories {
}

if (!project.ext.has('appShortcutBadgerVersion')) {
ext.appShortcutBadgerVersion = '1.1.19'
ext.appShortcutBadgerVersion = '1.1.22'
}

dependencies {
compile "me.leolin:ShortcutBadger:${appShortcutBadgerVersion}@aar"
implementation "me.leolin:ShortcutBadger:${appShortcutBadgerVersion}@aar"
}
Loading