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

Commit b343f50

Browse files
authored
[Android] notification with inline reply (#612)
1 parent fa0bd1b commit b343f50

File tree

5 files changed

+84
-8
lines changed

5 files changed

+84
-8
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,31 @@ Make sure you have the receiver in `AndroidManifest.xml`:
653653

654654
For iOS, you can use this [package](https://github.com/holmesal/react-native-ios-notification-actions) to add notification actions.
655655

656+
Notifications with inline reply:
657+
658+
You must register an action as "ReplyInput", this will show in the notifications an input to write in.
659+
660+
EXAMPLE:
661+
```javascript
662+
PushNotification.localNotificationSchedule({
663+
message: "My Notification Message", // (required)
664+
date: new Date(Date.now() + (60 * 1000)), // in 60 secs
665+
actions: ["ReplyInput"],
666+
reply_placeholder_text: "Write your response...", // (required)
667+
reply_button_text: "Reply" // (required)
668+
});
669+
```
670+
671+
To get the text from the notification:
672+
673+
```javascript
674+
...
675+
if(notification.action === "ReplyInput"){
676+
console.log("texto", notification.reply_text)// this will contain the inline reply text.
677+
}
678+
...
679+
680+
656681
## Set application badge icon
657682

658683
`PushNotification.setApplicationIconBadgeNumber(number: number)`

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import android.content.Intent;
99
import android.content.IntentFilter;
1010
import android.os.Bundle;
11-
1211
import androidx.annotation.NonNull;
1312
import androidx.core.app.NotificationManagerCompat;
1413

@@ -41,6 +40,7 @@
4140

4241
public class RNPushNotification extends ReactContextBaseJavaModule implements ActivityEventListener {
4342
public static final String LOG_TAG = "RNPushNotification";// all logging should use this tag
43+
public static final String KEY_TEXT_REPLY = "key_text_reply";
4444

4545
private RNPushNotificationHelper mRNPushNotificationHelper;
4646
private final SecureRandom mRandomNumberGenerator = new SecureRandom();
@@ -95,7 +95,7 @@ public void onNewIntent(Intent intent) {
9595
mJsDelivery.notifyNotification(bundle);
9696
}
9797
}
98-
98+
9999
@ReactMethod
100100
public void invokeApp(ReadableMap data) {
101101
Bundle bundle = null;

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
import com.facebook.react.ReactApplication;
1414
import com.facebook.react.ReactInstanceManager;
1515
import com.facebook.react.bridge.ReactContext;
16+
import androidx.core.app.RemoteInput;
1617

1718
import static com.dieam.reactnativepushnotification.modules.RNPushNotification.LOG_TAG;
19+
import static com.dieam.reactnativepushnotification.modules.RNPushNotification.KEY_TEXT_REPLY;
1820

1921
public class RNPushNotificationActions extends BroadcastReceiver {
2022
@Override
@@ -28,7 +30,15 @@ public void onReceive(final Context context, Intent intent) {
2830
}
2931

3032
final Bundle bundle = intent.getBundleExtra("notification");
33+
Bundle remoteInput = null;
3134

35+
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT_WATCH){
36+
remoteInput = RemoteInput.getResultsFromIntent(intent);
37+
}
38+
if (remoteInput != null) {
39+
// Add to reply_text the text written by the user in the notification
40+
bundle.putCharSequence("reply_text", remoteInput.getCharSequence(KEY_TEXT_REPLY));
41+
}
3242
// Dismiss the notification popup.
3343
NotificationManager manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
3444
int notificationID = Integer.parseInt(bundle.getString("id"));
@@ -87,4 +97,4 @@ public void onReactContextInitialized(ReactContext context) {
8797
});
8898
}
8999
}
90-
}
100+
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public class RNPushNotificationAttributes {
4747
private static final String TIMEOUT_AFTER = "timeoutAfter";
4848
private static final String ONLY_ALERT_ONCE = "onlyAlertOnce";
4949
private static final String ONGOING = "ongoing";
50+
private static final String REPLY_BUTTON_TEXT = "reply_button_text";
51+
private static final String REPLAY_PLACEHOLDER_TEXT = "reply_placeholder_text";
5052
private static final String ALLOW_WHILE_IDLE = "allowWhileIdle";
5153
private static final String IGNORE_IN_FOREGROUND = "ignoreInForeground";
5254

@@ -84,6 +86,8 @@ public class RNPushNotificationAttributes {
8486
private final double timeoutAfter;
8587
private final boolean onlyAlertOnce;
8688
private final boolean ongoing;
89+
private final String reply_button_text;
90+
private final String reply_placeholder_text;
8791
private final boolean allowWhileIdle;
8892
private final boolean ignoreInForeground;
8993

@@ -122,6 +126,8 @@ public RNPushNotificationAttributes(Bundle bundle) {
122126
timeoutAfter = bundle.getDouble(TIMEOUT_AFTER);
123127
onlyAlertOnce = bundle.getBoolean(ONLY_ALERT_ONCE);
124128
ongoing = bundle.getBoolean(ONGOING);
129+
reply_button_text = bundle.getString(REPLY_BUTTON_TEXT);
130+
reply_placeholder_text = bundle.getString(REPLAY_PLACEHOLDER_TEXT);
125131
allowWhileIdle = bundle.getBoolean(ALLOW_WHILE_IDLE);
126132
ignoreInForeground = bundle.getBoolean(IGNORE_IN_FOREGROUND);
127133
}
@@ -162,6 +168,8 @@ private RNPushNotificationAttributes(JSONObject jsonObject) {
162168
timeoutAfter = jsonObject.has(TIMEOUT_AFTER) ? jsonObject.getDouble(TIMEOUT_AFTER) : -1;
163169
onlyAlertOnce = jsonObject.has(ONLY_ALERT_ONCE) ? jsonObject.getBoolean(ONLY_ALERT_ONCE) : false;
164170
ongoing = jsonObject.has(ONGOING) ? jsonObject.getBoolean(ONGOING) : false;
171+
reply_button_text = jsonObject.has(REPLY_BUTTON_TEXT) ? jsonObject.getString(REPLY_BUTTON_TEXT) : null;
172+
reply_placeholder_text = jsonObject.has(REPLAY_PLACEHOLDER_TEXT) ? jsonObject.getString(REPLAY_PLACEHOLDER_TEXT) : null;
165173
allowWhileIdle = jsonObject.has(ALLOW_WHILE_IDLE) ? jsonObject.getBoolean(ALLOW_WHILE_IDLE) : false;
166174
ignoreInForeground = jsonObject.has(IGNORE_IN_FOREGROUND) ? jsonObject.getBoolean(IGNORE_IN_FOREGROUND) : false;
167175
} catch (JSONException e) {
@@ -259,6 +267,8 @@ public Bundle toBundle() {
259267
bundle.putDouble(TIMEOUT_AFTER, timeoutAfter);
260268
bundle.putBoolean(ONLY_ALERT_ONCE, onlyAlertOnce);
261269
bundle.putBoolean(ONGOING, ongoing);
270+
bundle.putString(REPLY_BUTTON_TEXT, reply_button_text);
271+
bundle.putString(REPLAY_PLACEHOLDER_TEXT, reply_placeholder_text);
262272
bundle.putBoolean(ALLOW_WHILE_IDLE, allowWhileIdle);
263273
bundle.putBoolean(IGNORE_IN_FOREGROUND, ignoreInForeground);
264274
return bundle;
@@ -301,6 +311,8 @@ public JSONObject toJson() {
301311
jsonObject.put(TIMEOUT_AFTER, timeoutAfter);
302312
jsonObject.put(ONLY_ALERT_ONCE, onlyAlertOnce);
303313
jsonObject.put(ONGOING, ongoing);
314+
jsonObject.put(REPLY_BUTTON_TEXT, reply_button_text);
315+
jsonObject.put(REPLAY_PLACEHOLDER_TEXT, reply_placeholder_text);
304316
jsonObject.put(ALLOW_WHILE_IDLE, allowWhileIdle);
305317
jsonObject.put(IGNORE_IN_FOREGROUND, ignoreInForeground);
306318
} catch (JSONException e) {
@@ -349,6 +361,8 @@ public String toString() {
349361
", timeoutAfter=" + timeoutAfter +
350362
", onlyAlertOnce=" + onlyAlertOnce +
351363
", ongoing=" + ongoing +
364+
", reply_button_text=" + reply_button_text +
365+
", reply_placeholder_text=" + reply_placeholder_text +
352366
", allowWhileIdle=" + allowWhileIdle +
353367
", ignoreInForeground=" + ignoreInForeground +
354368
'}';

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

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
import android.os.Bundle;
2424
import android.service.notification.StatusBarNotification;
2525
import android.util.Log;
26+
import androidx.core.app.RemoteInput;
27+
28+
import androidx.annotation.RequiresApi;
29+
import androidx.core.app.NotificationCompat;
2630

2731
import androidx.annotation.RequiresApi;
2832
import androidx.core.app.NotificationCompat;
@@ -46,6 +50,7 @@
4650

4751
import static com.dieam.reactnativepushnotification.modules.RNPushNotification.LOG_TAG;
4852
import static com.dieam.reactnativepushnotification.modules.RNPushNotificationAttributes.fromJson;
53+
import static com.dieam.reactnativepushnotification.modules.RNPushNotification.KEY_TEXT_REPLY;
4954

5055
public class RNPushNotificationHelper {
5156
public static final String PREFERENCES_KEY = "rn_push_notification";
@@ -514,13 +519,35 @@ public void sendToNotificationCentreWithPicture(Bundle bundle, Bitmap largeIconB
514519

515520
PendingIntent pendingActionIntent = PendingIntent.getBroadcast(context, notificationID, actionIntent,
516521
PendingIntent.FLAG_UPDATE_CURRENT);
517-
518-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
519-
notification.addAction(new NotificationCompat.Action.Builder(icon, action, pendingActionIntent).build());
520-
} else {
521-
notification.addAction(icon, action, pendingActionIntent);
522+
if(action.equals("ReplyInput")){
523+
//Action with inline reply
524+
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT_WATCH){
525+
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
526+
.setLabel(bundle.getString("reply_placeholder_text"))
527+
.build();
528+
NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder(
529+
icon, bundle.getString("reply_button_text"), pendingActionIntent)
530+
.addRemoteInput(remoteInput)
531+
.setAllowGeneratedReplies(true)
532+
.build();
533+
534+
notification.addAction(replyAction);
535+
}
536+
else{
537+
// The notification will not have action
538+
break;
539+
}
540+
}
541+
else{
542+
// Add "action" for later identifying which button gets pressed
543+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
544+
notification.addAction(new NotificationCompat.Action.Builder(icon, action, pendingActionIntent).build());
545+
} else {
546+
notification.addAction(icon, action, pendingActionIntent);
547+
}
522548
}
523549
}
550+
524551
}
525552

526553
// Remove the notification from the shared preferences once it has been shown

0 commit comments

Comments
 (0)