Android Create Custom Notifications
Create Custom Layouts
Unity Layout
Open your project in Unity and navigate to Assets/Plugins/Android/OneSignalConfig.plugin/res/
Create a folder called layout

Add two .xml
files: notification_small.xml
and notification_large.xml
using the code samples below. Jump to code samples.
Native and Non-Unity SDKs
Open your project in Android Studio and navigate to app/res/layout
and create New > Layout Resource File

Name the file notification_small
and click OK.

Repeat this process for another file called notification_large
.
Add the following code based on the file name.
Custom Layout Code Samples
You can create 2 default images named small_image
and large_image
if you want and put them in app/Java/res/drawable
. Otherwise remove android:src
from the code below.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="64dp"
android:gravity="center">
<ImageView
android:id="@+id/image_view_notification_small"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/small_image"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="256dp"
android:gravity="center">
<ImageView
android:id="@+id/image_view_notification_large"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/large_image"/>
</LinearLayout>

Setup Notification Service Extension
Create a file called NotificationServiceExtension.java
Unity NotificationServiceExtension
Create a new folder called OneSignalNotificationServiceExtension
within your Assets
folder.
Add NotificationServiceExtension.java
file so it is available like this: Assets/OneSignalNotificationServiceExtension/NotificationServiceExtension
Make sure only Android is selected in the Inspector for this file.

Then add the below Android SDK 3.x.x Java code to the NotificationServiceExtension.java
file.
Native and Non-Unity SDKs NotificationServiceExtension
Add this file to app/Java/YOUR_APP
Add the following code based on the version of the OneSignal SDK you are using:
package your.package.name
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.RemoteViews;
import org.json.JSONObject;
import com.onesignal.OSNotification;
import com.onesignal.OSMutableNotification;
import com.onesignal.OSNotificationReceivedEvent;
import com.onesignal.OneSignal.OSRemoteNotificationReceivedHandler;
import java.net.URL;
@SuppressWarnings("unused")
public class NotificationServiceExtension implements OSRemoteNotificationReceivedHandler {
@Override
public void remoteNotificationReceived(Context context, OSNotificationReceivedEvent notificationReceivedEvent) {
// https://developer.android.com/training/notify-user/custom-notification
// Get the layouts to use in the custom notification
RemoteViews notificationSmallLayoutView = new RemoteViews(context.getPackageName(), R.layout.notification_small);
RemoteViews notificationLargeLayoutView = new RemoteViews(context.getPackageName(), R.layout.notification_large);
OSNotification notification = notificationReceivedEvent.getNotification();
OSMutableNotification mutableNotification = notification.mutableCopy();
JSONObject data = notification.getAdditionalData();
String notification_small_image_url;
String notification_large_image_url;
if (data != null) {
Log.i("OneSignalExample", "Received Notification Data: " + data);
notification_small_image_url = data.optString("notification_small_image_url", null);
notification_large_image_url = data.optString("notification_large_image_url", null);
if (notification_small_image_url != null && notification_large_image_url != null) {
Log.i("OneSignalExample", "Received Notification Data notification_small_image_url: " + notification_small_image_url);
notificationSmallLayoutView.setImageViewBitmap(R.id.image_view_notification_small, getBitmapFromURL(notification_small_image_url));
notificationLargeLayoutView.setImageViewBitmap(R.id.image_view_notification_large, getBitmapFromURL(notification_large_image_url));
mutableNotification.setExtender(builder -> builder.setCustomContentView(notificationSmallLayoutView)
.setCustomBigContentView(notificationLargeLayoutView)
//.setStyle(new NotificationCompat.DecoratedCustomViewStyle())//recommended for full background and app title
);
}
}
// If complete isn't call within a time period of 25 seconds, OneSignal internal logic will show the original notification
// To omit displaying a notification, pass `null` to complete()
notificationReceivedEvent.complete(mutableNotification);
}
private static Bitmap getBitmapFromURL(String location) {
try {
return BitmapFactory.decodeStream(new URL(location).openConnection().getInputStream());
} catch (Throwable t) {
Log.i("OneSignalExample", "COULD NOT DOWNLOAD IMAGE");
}
return null;
}
}
package com.onesignal.onesignalsdk;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.app.NotificationCompat;
import com.onesignal.BuildConfig;
import com.onesignal.OSNotificationDisplayedResult;
import com.onesignal.OSNotificationPayload;
import com.onesignal.NotificationExtenderService;
import com.onesignal.OSNotificationReceivedResult;
import java.net.URL;
import android.util.Log;
import android.widget.RemoteViews;
import android.content.Context;
import android.content.Intent;
//import androidx.core.app.NotificationCompat;
import org.json.JSONObject;
public class NotificationServiceExtension extends NotificationExtenderService {
@Override
protected boolean onNotificationProcessing(final OSNotificationReceivedResult receivedResult) {
Log.d("OneSignalExtension", "onNotificationProcessing invoked");
// https://developer.android.com/training/notify-user/custom-notification
// Get the layouts to use in the custom notification
final RemoteViews notificationSmallLayoutView = new RemoteViews(getPackageName(), R.layout.notification_small);
final RemoteViews notificationLargeLayoutView = new RemoteViews(getPackageName(), R.layout.notification_large);
final JSONObject data = receivedResult.payload.additionalData;
OverrideSettings overrideSettings = new OverrideSettings();
overrideSettings.extender = new NotificationCompat.Extender() {
@Override
public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {
Log.d("OneSignalExtension", "Notification received with payload: " + receivedResult.payload);
String notification_small_image_url;
String notification_large_image_url;
if (data != null){
notification_small_image_url = data.optString("notification_small_image_url", null);
notification_large_image_url = data.optString("notification_large_image_url", null);
if (notification_small_image_url != null && notification_large_image_url != null) {
Log.d("OneSignalExtension", "notification_small_image_url: " + notification_small_image_url);
Log.d("OneSignalExtension", "notification_large_image_url: " + notification_large_image_url);
notificationSmallLayoutView.setImageViewBitmap(R.id.image_view_notification_small, getBitmapFromURL(notification_small_image_url));
notificationLargeLayoutView.setImageViewBitmap(R.id.image_view_notification_large, getBitmapFromURL(notification_large_image_url));
builder.setCustomContentView(notificationSmallLayoutView);
builder.setCustomBigContentView(notificationLargeLayoutView);
//.setStyle(new NotificationCompat.DecoratedCustomViewStyle())//recommended for full background and app title
}
}
return builder;
}
};
OSNotificationDisplayedResult displayedResult = displayNotification(overrideSettings);
Log.d("OneSignalExtension", "Notification displayed with id: " + displayedResult.androidNotificationId);
// Return true to stop the notification from displaying.
return false;
}
private static Bitmap getBitmapFromURL(String location) {
try {
return BitmapFactory.decodeStream(new URL(location).openConnection().getInputStream());
} catch (Throwable t) {
Log.i("OneSignalExample", "COULD NOT DOWNLOAD IMAGE");
}
return null;
}
}
Unity AndroidManifest.xml Setup
Within your Assets/Plugins/Android/AndroidManifest.xml
file.

If you don't have this file, check you Build Settings > Android > Player Settings > Publish Settings > Custom Android Manifest is checked.

Add the below <service>
code within the <application>
... </application>
tags
<service
android:name="com.onesignal.onesignalsdk.NotificationServiceExtension"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false">
<intent-filter>
<action android:name="com.onesignal.NotificationServiceExtension" />
</intent-filter>
</service>
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unity3d.player"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
<service
android:name="com.onesignal.onesignalsdk.NotificationServiceExtension"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false">
<intent-filter>
<action android:name="com.onesignal.NotificationExtender" />
</intent-filter>
</service>
</application>
</manifest>
Send the Notification
Within the OneSignal Dashboard, use the "Additional Data" fields to add:
notification_small_image_url
and notification_large_image_url
as keys with the image url as value.
For example:
notification_small_image_url
: https://cdn.pixabay.com/photo/2019/05/29/16/00/retro-4237850_960_720.jpg
notification_large_image_url
: https://cdn.pixabay.com/photo/2015/12/23/22/36/minecraft-1106252_960_720.jpg

Updated almost 2 years ago