Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.

Commit 4f685aa

Browse files
committed
Fix Actions when in killed state.
1 parent fc077c6 commit 4f685aa

File tree

8 files changed

+128
-73
lines changed

8 files changed

+128
-73
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1313
- `RNPushNotificationRegistrationService` has been removed, old reference in AndroidManifest must be removed.
1414
- `Notifications.registerNotificationActions()` has been removed and is not required for `actions`.
1515
- `DeviceEventEmitter.addListener('notificationActionReceived', callback)` is replaced by `onAction`.
16+
- Extra receiver must be added to manage actions.
17+
```xml
18+
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
19+
```
1620

1721
### Features
1822

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ In your `android/app/src/main/AndroidManifest.xml`
9393
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
9494
android:resource="@color/white"/> <!-- or @android:color/{name} to use a standard color -->
9595

96+
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
9697
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
9798
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
9899
<intent-filter>
@@ -596,6 +597,11 @@ For e.g. `actions: ['Accept', 'Reject']`
596597

597598
When you handle actions in background (`invokeApp: false`), you can open the application and pass the initial notification by using use `PushNotification.invokeApp(notification)`.
598599

600+
Make sure you have the receiver in `AndroidManifest.xml`:
601+
```xml
602+
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
603+
```
604+
599605
For iOS, you can use this [package](https://github.com/holmesal/react-native-ios-notification-actions) to add notification actions.
600606

601607
## Set application badge icon

android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotification.java

Lines changed: 1 addition & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ public RNPushNotification(ReactApplicationContext reactContext) {
5959
mJsDelivery = new RNPushNotificationJsDelivery(reactContext);
6060

6161
mRNPushNotificationHelper.checkOrCreateDefaultChannel();
62-
63-
registerNotificationsReceiveNotificationActions();
6462
}
6563

6664
@Override
@@ -94,70 +92,6 @@ public void onNewIntent(Intent intent) {
9492
mJsDelivery.notifyNotification(bundle);
9593
}
9694
}
97-
98-
private void registerNotificationsReceiveNotificationActions() {
99-
IntentFilter intentFilter = new IntentFilter();
100-
101-
for(int i = 0; i < 10; i++) {
102-
intentFilter.addAction(getReactApplicationContext().getPackageName() + ".ACTION_" + i);
103-
}
104-
105-
final RNPushNotification self = this;
106-
107-
getReactApplicationContext().registerReceiver(new BroadcastReceiver() {
108-
@Override
109-
public void onReceive(Context context, Intent intent) {
110-
Bundle bundle = intent.getBundleExtra("notification");
111-
112-
// Dismiss the notification popup.
113-
NotificationManager manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
114-
int notificationID = Integer.parseInt(bundle.getString("id"));
115-
116-
boolean autoCancel = bundle.getBoolean("autoCancel", true);
117-
118-
if(autoCancel) {
119-
if (bundle.containsKey("tag")) {
120-
String tag = bundle.getString("tag");
121-
manager.cancel(tag, notificationID);
122-
} else {
123-
manager.cancel(notificationID);
124-
}
125-
}
126-
127-
boolean invokeApp = bundle.getBoolean("invokeApp", true);
128-
129-
// Notify the action.
130-
if(invokeApp) {
131-
self.invokeApp(bundle);
132-
} else {
133-
mJsDelivery.notifyNotificationAction(bundle);
134-
}
135-
}
136-
}, intentFilter);
137-
}
138-
139-
private void invokeApp(Bundle bundle) {
140-
ReactContext reactContext = getReactApplicationContext();
141-
String packageName = reactContext.getPackageName();
142-
Intent launchIntent = reactContext.getPackageManager().getLaunchIntentForPackage(packageName);
143-
String className = launchIntent.getComponent().getClassName();
144-
145-
try {
146-
Class<?> activityClass = Class.forName(className);
147-
Intent activityIntent = new Intent(reactContext, activityClass);
148-
149-
if(bundle != null) {
150-
activityIntent.putExtra("notification", bundle);
151-
}
152-
153-
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
154-
155-
reactContext.startActivity(activityIntent);
156-
} catch(Exception e) {
157-
Log.e(LOG_TAG, "Class not found", e);
158-
return;
159-
}
160-
}
16195

16296
@ReactMethod
16397
public void invokeApp(ReadableMap data) {
@@ -167,7 +101,7 @@ public void invokeApp(ReadableMap data) {
167101
bundle = Arguments.toBundle(data);
168102
}
169103

170-
invokeApp(bundle);
104+
mRNPushNotificationHelper.invokeApp(bundle);
171105
}
172106

173107
@ReactMethod
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.dieam.reactnativepushnotification.modules;
2+
3+
import android.app.Application;
4+
import android.app.NotificationManager;
5+
import android.content.BroadcastReceiver;
6+
import android.content.Context;
7+
import android.content.Intent;
8+
import android.os.Bundle;
9+
import android.os.Handler;
10+
import android.os.Looper;
11+
import android.util.Log;
12+
13+
import com.facebook.react.ReactApplication;
14+
import com.facebook.react.ReactInstanceManager;
15+
import com.facebook.react.bridge.ReactContext;
16+
17+
import static com.dieam.reactnativepushnotification.modules.RNPushNotification.LOG_TAG;
18+
19+
public class RNPushNotificationActions extends BroadcastReceiver {
20+
@Override
21+
public void onReceive(final Context context, Intent intent) {
22+
String intentActionPrefix = context.getPackageName() + ".ACTION_";
23+
24+
Log.i(LOG_TAG, "RNPushNotificationActions loading action");
25+
26+
final Bundle bundle = intent.getBundleExtra("notification");
27+
28+
// Dismiss the notification popup.
29+
NotificationManager manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
30+
int notificationID = Integer.parseInt(bundle.getString("id"));
31+
32+
boolean autoCancel = bundle.getBoolean("autoCancel", true);
33+
34+
if(autoCancel) {
35+
if (bundle.containsKey("tag")) {
36+
String tag = bundle.getString("tag");
37+
manager.cancel(tag, notificationID);
38+
} else {
39+
manager.cancel(notificationID);
40+
}
41+
}
42+
43+
boolean invokeApp = bundle.getBoolean("invokeApp", true);
44+
45+
// Notify the action.
46+
if(invokeApp) {
47+
RNPushNotificationHelper helper = new RNPushNotificationHelper((Application) context.getApplicationContext());
48+
49+
helper.invokeApp(bundle);
50+
} else {
51+
52+
// We need to run this on the main thread, as the React code assumes that is true.
53+
// Namely, DevServerHelper constructs a Handler() without a Looper, which triggers:
54+
// "Can't create handler inside thread that has not called Looper.prepare()"
55+
Handler handler = new Handler(Looper.getMainLooper());
56+
handler.post(new Runnable() {
57+
public void run() {
58+
// Construct and load our normal React JS code bundle
59+
final ReactInstanceManager mReactInstanceManager = ((ReactApplication) context.getApplicationContext()).getReactNativeHost().getReactInstanceManager();
60+
ReactContext context = mReactInstanceManager.getCurrentReactContext();
61+
// If it's constructed, send a notification
62+
if (context != null) {
63+
RNPushNotificationJsDelivery mJsDelivery = new RNPushNotificationJsDelivery(context);
64+
65+
mJsDelivery.notifyNotificationAction(bundle);
66+
} else {
67+
// Otherwise wait for construction, then send the notification
68+
mReactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
69+
public void onReactContextInitialized(ReactContext context) {
70+
RNPushNotificationJsDelivery mJsDelivery = new RNPushNotificationJsDelivery(context);
71+
72+
mJsDelivery.notifyNotificationAction(bundle);
73+
74+
mReactInstanceManager.removeReactInstanceEventListener(this);
75+
}
76+
});
77+
if (!mReactInstanceManager.hasStartedCreatingInitialContext()) {
78+
// Construct it in the background
79+
mReactInstanceManager.createReactContextInBackground();
80+
}
81+
}
82+
}
83+
});
84+
}
85+
}
86+
}

android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import android.app.NotificationChannel;
99
import android.app.NotificationManager;
1010
import android.app.PendingIntent;
11-
import android.content.BroadcastReceiver;
1211
import android.content.Context;
1312
import android.content.Intent;
1413
import android.content.SharedPreferences;
@@ -29,6 +28,7 @@
2928
import androidx.core.app.NotificationCompat;
3029

3130
import com.facebook.react.bridge.Arguments;
31+
import com.facebook.react.bridge.ReactContext;
3232
import com.facebook.react.bridge.ReadableArray;
3333
import com.facebook.react.bridge.ReadableMap;
3434
import com.facebook.react.bridge.WritableArray;
@@ -81,6 +81,28 @@ private AlarmManager getAlarmManager() {
8181
return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
8282
}
8383

84+
public void invokeApp(Bundle bundle) {
85+
String packageName = context.getPackageName();
86+
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
87+
String className = launchIntent.getComponent().getClassName();
88+
89+
try {
90+
Class<?> activityClass = Class.forName(className);
91+
Intent activityIntent = new Intent(context, activityClass);
92+
93+
if(bundle != null) {
94+
activityIntent.putExtra("notification", bundle);
95+
}
96+
97+
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
98+
99+
context.startActivity(activityIntent);
100+
} catch(Exception e) {
101+
Log.e(LOG_TAG, "Class not found", e);
102+
return;
103+
}
104+
}
105+
84106
private PendingIntent toScheduleNotificationIntent(Bundle bundle) {
85107
try {
86108
int notificationID = Integer.parseInt(bundle.getString("id"));
@@ -522,7 +544,7 @@ public void sendToNotificationCentreWithPicture(Bundle bundle, Bitmap largeIconB
522544
}
523545

524546

525-
Intent actionIntent = new Intent(packageName + ".ACTION_" + i);
547+
Intent actionIntent = new Intent(context, RNPushNotificationActions.class);
526548

527549
actionIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
528550

android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationJsDelivery.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import android.os.Bundle;
55

66
import com.facebook.react.bridge.Arguments;
7-
import com.facebook.react.bridge.ReactApplicationContext;
7+
import com.facebook.react.bridge.ReactContext;
88
import com.facebook.react.bridge.WritableMap;
99
import com.facebook.react.modules.core.DeviceEventManagerModule;
1010

@@ -18,9 +18,9 @@
1818
*/
1919

2020
public class RNPushNotificationJsDelivery {
21-
private ReactApplicationContext mReactContext;
21+
private ReactContext mReactContext;
2222

23-
public RNPushNotificationJsDelivery(ReactApplicationContext reactContext) {
23+
public RNPushNotificationJsDelivery(ReactContext reactContext) {
2424
mReactContext = reactContext;
2525
}
2626

example/NotificationHandler.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ class NotificationHandler {
2222
console.log(notification.action);
2323
console.log(notification);
2424

25-
PushNotification.invokeApp(notification);
25+
if(notification.action === 'Yes') {
26+
PushNotification.invokeApp(notification);
27+
}
2628
}
2729

2830
attachRegister(handler) {

example/android/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
</activity>
3030
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
3131

32+
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
3233
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
3334
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
3435
<intent-filter>

0 commit comments

Comments
 (0)