Skip to content

Commit 2c07466

Browse files
committed
Supported avatarUrl for remote notification.
1 parent bdf8825 commit 2c07466

File tree

9 files changed

+287
-140
lines changed

9 files changed

+287
-140
lines changed

android/src/main/java/com/azure/reactnative/notificationhub/ReactNativeConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public final class ReactNativeConstants {
6363
public static final String KEY_REMOTE_NOTIFICATION_TAG = "tag";
6464
public static final String KEY_REMOTE_NOTIFICATION_USER_INTERACTION = "userInteraction";
6565
public static final String KEY_REMOTE_NOTIFICATION_COLDSTART = "coldstart";
66+
public static final String KEY_REMOTE_NOTIFICATION_AVATAR_URL = "avatarUrl";
6667

6768
// Remote notification payload's priority
6869
public static final String REMOTE_NOTIFICATION_PRIORITY_MAX = "max";
@@ -101,6 +102,7 @@ public final class ReactNativeConstants {
101102
public static final String ERROR_NOTIFICATION_HUB = "E_NOTIFICATION_HUB";
102103
public static final String ERROR_NOT_REGISTERED = "E_NOT_REGISTERED";
103104
public static final String ERROR_NOT_REGISTERED_DESC = "No registration to Azure Notification Hub.";
105+
public static final String ERROR_FETCH_IMAGE = "Error while fetching image.";
104106

105107
private ReactNativeConstants() {
106108
}

android/src/main/java/com/azure/reactnative/notificationhub/ReactNativeNotificationHubModule.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,7 @@ public void onHostResume() {
176176
if (intent != null) {
177177
Bundle bundle = ReactNativeUtil.getBundleFromIntent(intent);
178178
if (bundle != null) {
179-
if (intent.hasExtra(KEY_NOTIFICATION_PAYLOAD_TYPE)) {
180-
intent.removeExtra(KEY_NOTIFICATION_PAYLOAD_TYPE);
181-
}
182-
179+
ReactNativeUtil.removeNotificationFromIntent(intent);
183180
bundle.putBoolean(KEY_REMOTE_NOTIFICATION_FOREGROUND, false);
184181
bundle.putBoolean(KEY_REMOTE_NOTIFICATION_USER_INTERACTION, true);
185182
bundle.putBoolean(KEY_REMOTE_NOTIFICATION_COLDSTART, true);

android/src/main/java/com/azure/reactnative/notificationhub/ReactNativeNotificationsHandler.java

Lines changed: 134 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -73,126 +73,142 @@ public void run() {
7373
*
7474
* Example: {"data":{"message":"Notification Hub test notification"}}
7575
*/
76-
public static void sendNotification(Context context, Bundle bundle, String notificationChannelID) {
77-
try {
78-
Class intentClass = ReactNativeUtil.getMainActivityClass(context);
79-
if (intentClass == null) {
80-
Log.e(TAG, ERROR_NO_ACTIVITY_CLASS);
81-
return;
82-
}
83-
84-
String message = bundle.getString(KEY_REMOTE_NOTIFICATION_MESSAGE);
85-
if (message == null) {
86-
message = bundle.getString(KEY_REMOTE_NOTIFICATION_BODY);
87-
}
88-
89-
if (message == null) {
90-
Log.e(TAG, ERROR_NO_MESSAGE);
91-
return;
92-
}
93-
94-
Resources res = context.getResources();
95-
String packageName = context.getPackageName();
96-
97-
String title = bundle.getString(KEY_REMOTE_NOTIFICATION_TITLE);
98-
if (title == null) {
99-
ApplicationInfo appInfo = context.getApplicationInfo();
100-
title = context.getPackageManager().getApplicationLabel(appInfo).toString();
101-
}
102-
103-
int priority = ReactNativeUtil.getNotificationCompatPriority(
104-
bundle.getString(KEY_REMOTE_NOTIFICATION_PRIORITY));
105-
NotificationCompat.Builder notificationBuilder = ReactNativeUtil.initNotificationCompatBuilder(
106-
context,
107-
notificationChannelID,
108-
title,
109-
bundle.getString(KEY_REMOTE_NOTIFICATION_TICKER),
110-
NotificationCompat.VISIBILITY_PRIVATE,
111-
priority,
112-
bundle.getBoolean(KEY_REMOTE_NOTIFICATION_AUTO_CANCEL, true));
113-
114-
String group = bundle.getString(KEY_REMOTE_NOTIFICATION_GROUP);
115-
if (group != null) {
116-
notificationBuilder.setGroup(group);
117-
}
118-
119-
notificationBuilder.setContentText(message);
120-
121-
String subText = bundle.getString(KEY_REMOTE_NOTIFICATION_SUB_TEXT);
122-
if (subText != null) {
123-
notificationBuilder.setSubText(subText);
124-
}
125-
126-
String numberString = bundle.getString(KEY_REMOTE_NOTIFICATION_NUMBER);
127-
if (numberString != null) {
128-
notificationBuilder.setNumber(Integer.parseInt(numberString));
129-
}
130-
131-
int smallIconResId = ReactNativeUtil.getSmallIcon(bundle, res, packageName);
132-
notificationBuilder.setSmallIcon(smallIconResId);
133-
134-
String largeIcon = bundle.getString(KEY_REMOTE_NOTIFICATION_LARGE_ICON);
135-
int largeIconResId = ReactNativeUtil.getLargeIcon(bundle, largeIcon, res, packageName);
136-
Bitmap largeIconBitmap = BitmapFactory.decodeResource(res, largeIconResId);
137-
if (largeIconResId != 0 && (largeIcon != null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)) {
138-
notificationBuilder.setLargeIcon(largeIconBitmap);
139-
}
140-
141-
String bigText = bundle.getString(KEY_REMOTE_NOTIFICATION_BIG_TEXT);
142-
if (bigText == null) {
143-
bigText = message;
144-
}
145-
notificationBuilder.setStyle(ReactNativeUtil.getBigTextStyle(bigText));
146-
147-
// Create notification intent
148-
Intent intent = ReactNativeUtil.createNotificationIntent(context, bundle, intentClass);
149-
150-
if (!bundle.containsKey(KEY_REMOTE_NOTIFICATION_PLAY_SOUND) || bundle.getBoolean(KEY_REMOTE_NOTIFICATION_PLAY_SOUND)) {
151-
Uri soundUri = ReactNativeUtil.getSoundUri(context, bundle);
152-
notificationBuilder.setSound(soundUri);
153-
}
154-
155-
if (bundle.containsKey(KEY_REMOTE_NOTIFICATION_ONGOING)) {
156-
notificationBuilder.setOngoing(bundle.getBoolean(KEY_REMOTE_NOTIFICATION_ONGOING));
157-
}
158-
159-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
160-
notificationBuilder.setCategory(NotificationCompat.CATEGORY_CALL);
161-
162-
String color = bundle.getString(KEY_REMOTE_NOTIFICATION_COLOR);
163-
if (color != null) {
164-
notificationBuilder.setColor(Color.parseColor(color));
76+
public static void sendNotification(final Context context,
77+
final Bundle bundle,
78+
final String notificationChannelID) {
79+
ReactNativeUtil.runInWorkerThread(new Runnable() {
80+
public void run() {
81+
try {
82+
Class intentClass = ReactNativeUtil.getMainActivityClass(context);
83+
if (intentClass == null) {
84+
Log.e(TAG, ERROR_NO_ACTIVITY_CLASS);
85+
return;
86+
}
87+
88+
String message = bundle.getString(KEY_REMOTE_NOTIFICATION_MESSAGE);
89+
if (message == null) {
90+
message = bundle.getString(KEY_REMOTE_NOTIFICATION_BODY);
91+
}
92+
93+
if (message == null) {
94+
Log.e(TAG, ERROR_NO_MESSAGE);
95+
return;
96+
}
97+
98+
Resources res = context.getResources();
99+
String packageName = context.getPackageName();
100+
101+
String title = bundle.getString(KEY_REMOTE_NOTIFICATION_TITLE);
102+
if (title == null) {
103+
ApplicationInfo appInfo = context.getApplicationInfo();
104+
title = context.getPackageManager().getApplicationLabel(appInfo).toString();
105+
}
106+
107+
int priority = ReactNativeUtil.getNotificationCompatPriority(
108+
bundle.getString(KEY_REMOTE_NOTIFICATION_PRIORITY));
109+
NotificationCompat.Builder notificationBuilder = ReactNativeUtil.initNotificationCompatBuilder(
110+
context,
111+
notificationChannelID,
112+
title,
113+
bundle.getString(KEY_REMOTE_NOTIFICATION_TICKER),
114+
NotificationCompat.VISIBILITY_PRIVATE,
115+
priority,
116+
bundle.getBoolean(KEY_REMOTE_NOTIFICATION_AUTO_CANCEL, true));
117+
118+
String group = bundle.getString(KEY_REMOTE_NOTIFICATION_GROUP);
119+
if (group != null) {
120+
notificationBuilder.setGroup(group);
121+
}
122+
123+
notificationBuilder.setContentText(message);
124+
125+
String subText = bundle.getString(KEY_REMOTE_NOTIFICATION_SUB_TEXT);
126+
if (subText != null) {
127+
notificationBuilder.setSubText(subText);
128+
}
129+
130+
String numberString = bundle.getString(KEY_REMOTE_NOTIFICATION_NUMBER);
131+
if (numberString != null) {
132+
notificationBuilder.setNumber(Integer.parseInt(numberString));
133+
}
134+
135+
int smallIconResId = ReactNativeUtil.getSmallIcon(bundle, res, packageName);
136+
notificationBuilder.setSmallIcon(smallIconResId);
137+
138+
if (bundle.getString(KEY_REMOTE_NOTIFICATION_AVATAR_URL) == null) {
139+
String largeIcon = bundle.getString(KEY_REMOTE_NOTIFICATION_LARGE_ICON);
140+
int largeIconResId = ReactNativeUtil.getLargeIcon(bundle, largeIcon, res, packageName);
141+
Bitmap largeIconBitmap = BitmapFactory.decodeResource(res, largeIconResId);
142+
if (largeIconResId != 0 && (
143+
largeIcon != null ||
144+
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)) {
145+
notificationBuilder.setLargeIcon(largeIconBitmap);
146+
}
147+
} else {
148+
Bitmap largeIconBitmap = ReactNativeUtil.fetchImage(
149+
bundle.getString(KEY_REMOTE_NOTIFICATION_AVATAR_URL));
150+
if (largeIconBitmap != null) {
151+
notificationBuilder.setLargeIcon(largeIconBitmap);
152+
}
153+
}
154+
155+
String bigText = bundle.getString(KEY_REMOTE_NOTIFICATION_BIG_TEXT);
156+
if (bigText == null) {
157+
bigText = message;
158+
}
159+
notificationBuilder.setStyle(ReactNativeUtil.getBigTextStyle(bigText));
160+
161+
// Create notification intent
162+
Intent intent = ReactNativeUtil.createNotificationIntent(context, bundle, intentClass);
163+
164+
if (!bundle.containsKey(KEY_REMOTE_NOTIFICATION_PLAY_SOUND) || bundle.getBoolean(KEY_REMOTE_NOTIFICATION_PLAY_SOUND)) {
165+
Uri soundUri = ReactNativeUtil.getSoundUri(context, bundle);
166+
notificationBuilder.setSound(soundUri);
167+
}
168+
169+
if (bundle.containsKey(KEY_REMOTE_NOTIFICATION_ONGOING)) {
170+
notificationBuilder.setOngoing(bundle.getBoolean(KEY_REMOTE_NOTIFICATION_ONGOING));
171+
}
172+
173+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
174+
notificationBuilder.setCategory(NotificationCompat.CATEGORY_CALL);
175+
176+
String color = bundle.getString(KEY_REMOTE_NOTIFICATION_COLOR);
177+
if (color != null) {
178+
notificationBuilder.setColor(Color.parseColor(color));
179+
}
180+
}
181+
182+
int notificationID = bundle.getString(KEY_REMOTE_NOTIFICATION_ID).hashCode();
183+
PendingIntent pendingIntent = PendingIntent.getActivity(context, notificationID, intent,
184+
PendingIntent.FLAG_UPDATE_CURRENT);
185+
notificationBuilder.setContentIntent(pendingIntent);
186+
187+
if (!bundle.containsKey(KEY_REMOTE_NOTIFICATION_VIBRATE) || bundle.getBoolean(KEY_REMOTE_NOTIFICATION_VIBRATE)) {
188+
long vibration = bundle.containsKey(KEY_REMOTE_NOTIFICATION_VIBRATION) ?
189+
(long) bundle.getDouble(KEY_REMOTE_NOTIFICATION_VIBRATION) : DEFAULT_VIBRATION;
190+
if (vibration == 0)
191+
vibration = DEFAULT_VIBRATION;
192+
notificationBuilder.setVibrate(new long[]{0, vibration});
193+
}
194+
195+
// Process notification's actions
196+
ReactNativeUtil.processNotificationActions(context, bundle, notificationBuilder, notificationID);
197+
198+
Notification notification = notificationBuilder.build();
199+
NotificationManager notificationManager = (NotificationManager) context.getSystemService(
200+
Context.NOTIFICATION_SERVICE);
201+
if (bundle.containsKey(KEY_REMOTE_NOTIFICATION_TAG)) {
202+
String tag = bundle.getString(KEY_REMOTE_NOTIFICATION_TAG);
203+
notificationManager.notify(tag, notificationID, notification);
204+
} else {
205+
notificationManager.notify(notificationID, notification);
206+
}
207+
} catch (Exception e) {
208+
Log.e(TAG, ERROR_SEND_PUSH_NOTIFICATION, e);
165209
}
166210
}
167-
168-
int notificationID = bundle.getString(KEY_REMOTE_NOTIFICATION_ID).hashCode();
169-
PendingIntent pendingIntent = PendingIntent.getActivity(context, notificationID, intent,
170-
PendingIntent.FLAG_UPDATE_CURRENT);
171-
notificationBuilder.setContentIntent(pendingIntent);
172-
173-
if (!bundle.containsKey(KEY_REMOTE_NOTIFICATION_VIBRATE) || bundle.getBoolean(KEY_REMOTE_NOTIFICATION_VIBRATE)) {
174-
long vibration = bundle.containsKey(KEY_REMOTE_NOTIFICATION_VIBRATION) ?
175-
(long) bundle.getDouble(KEY_REMOTE_NOTIFICATION_VIBRATION) : DEFAULT_VIBRATION;
176-
if (vibration == 0)
177-
vibration = DEFAULT_VIBRATION;
178-
notificationBuilder.setVibrate(new long[]{0, vibration});
179-
}
180-
181-
// Process notification's actions
182-
ReactNativeUtil.processNotificationActions(context, bundle, notificationBuilder, notificationID);
183-
184-
Notification notification = notificationBuilder.build();
185-
NotificationManager notificationManager = (NotificationManager) context.getSystemService(
186-
Context.NOTIFICATION_SERVICE);
187-
if (bundle.containsKey(KEY_REMOTE_NOTIFICATION_TAG)) {
188-
String tag = bundle.getString(KEY_REMOTE_NOTIFICATION_TAG);
189-
notificationManager.notify(tag, notificationID, notification);
190-
} else {
191-
notificationManager.notify(notificationID, notification);
192-
}
193-
} catch (Exception e) {
194-
Log.e(TAG, ERROR_SEND_PUSH_NOTIFICATION, e);
195-
}
211+
});
196212
}
197213

198214
private ReactNativeNotificationsHandler() {

android/src/main/java/com/azure/reactnative/notificationhub/ReactNativeUtil.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import android.content.Context;
55
import android.content.Intent;
66
import android.content.res.Resources;
7+
import android.graphics.Bitmap;
8+
import android.graphics.BitmapFactory;
79
import android.media.RingtoneManager;
810
import android.net.Uri;
911
import android.os.Bundle;
@@ -22,7 +24,10 @@
2224
import org.json.JSONException;
2325
import org.json.JSONObject;
2426

25-
import java.lang.invoke.WrongMethodTypeException;
27+
import java.io.InputStream;
28+
import java.net.HttpURLConnection;
29+
import java.net.MalformedURLException;
30+
import java.net.URL;
2631
import java.util.Set;
2732
import java.util.concurrent.ExecutorService;
2833
import java.util.concurrent.Executors;
@@ -32,7 +37,7 @@
3237
public final class ReactNativeUtil {
3338
public static final String TAG = "ReactNativeUtil";
3439

35-
private static final ExecutorService mPool = Executors.newFixedThreadPool(1);
40+
private static final ExecutorService mPool = Executors.newFixedThreadPool(2);
3641

3742
public static void runInWorkerThread(Runnable runnable) {
3843
mPool.execute(runnable);
@@ -299,10 +304,37 @@ public static Bundle getBundleFromIntent(Intent intent) {
299304
return bundle;
300305
}
301306

307+
public static void removeNotificationFromIntent(Intent intent) {
308+
if (intent.hasExtra(KEY_NOTIFICATION_PAYLOAD_TYPE)) {
309+
intent.removeExtra(KEY_NOTIFICATION_PAYLOAD_TYPE);
310+
} else if (intent.hasExtra(KEY_REMOTE_NOTIFICATION_ID)) {
311+
intent.removeExtra(KEY_REMOTE_NOTIFICATION_ID);
312+
}
313+
}
314+
302315
public static NotificationCompat.BigTextStyle getBigTextStyle(String bigText) {
303316
return new NotificationCompat.BigTextStyle().bigText(bigText);
304317
}
305318

319+
public static class UrlWrapper {
320+
public static HttpURLConnection openConnection(String url) throws Exception {
321+
return (HttpURLConnection)(new URL(url)).openConnection();
322+
}
323+
}
324+
325+
public static Bitmap fetchImage(String urlString) {
326+
try {
327+
HttpURLConnection connection = UrlWrapper.openConnection(urlString);
328+
connection.setDoInput(true);
329+
connection.connect();
330+
InputStream input = connection.getInputStream();
331+
return BitmapFactory.decodeStream(input);
332+
} catch (Exception e) {
333+
Log.e(TAG, ERROR_FETCH_IMAGE, e);
334+
return null;
335+
}
336+
}
337+
306338
private ReactNativeUtil() {
307339
}
308340
}

docs/android-installation.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ In `android/app/src/main/AndroidManifest.xml`
120120
<action android:name="com.google.firebase.MESSAGING_EVENT" />
121121
</intent-filter>
122122
</service>
123+
124+
<activity
125+
android:launchMode="singleTop"
126+
...>
127+
</activity>
123128
...
124129
```
125130

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
android:name=".MainActivity"
3333
android:label="@string/app_name"
3434
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
35+
android:launchMode="singleTop"
3536
android:windowSoftInputMode="adjustResize">
3637
<intent-filter>
3738
<action android:name="android.intent.action.MAIN" />

0 commit comments

Comments
 (0)