Retargeting
Your app can send information to indigitall's servers to identify the actions and events that happen in it. This allows you to automate retargeting actions.
To register these events you have to call the sendCustomEvent method, passing a descriptive ID as a parameter (you can invent the one you like best) and set data you need.
The data must be added in an array of the INHashMap model like the one in the example indicated below.
Com.Indigitall.Xamarin.Models.INHashMap[] iNHashMap = new Com.Indigitall.Xamarin.Models.INHashMap[2];
iNHashMap[0] = new Com.Indigitall.Xamarin.Models.INHashMap("key1", "value1");
iNHashMap[1] = new Com.Indigitall.Xamarin.Models.INHashMap("key2", "value2");
indigitall.SendCustomEvent("YOUR_CUSTOM_EVENT", iNHashMap, () =>
{
// Do something in success function
}, (ErrorDescription) =>
{
//ERROR DO SOMETHING
});
Topics
Our SDK allows you to classify users into different customizable groups. This is very useful for:
- Implement a preferences screen so that the user can choose the topics for which they want to receive notifications.
- Label according to the navigation or actions that the user performs.
- Segment communications according to whether the user has identified or is anonymous.
- Segment based on language, culture, customer category, or based on any other criteria you need.
Remember that you must first define the groups you want to work with in the indigitall console (Tools> Topics).
* List Groups
Use the topicsList method to get the list of groups that are configured in your indigitall project. The callback of this method receives as a parameter an array of Topics, which contains the information of all the available groups, as well as a flag that indicates whether the user is included in any of them.
indigitall.TopicsList((topic) =>
{
//DO SOMETHING
}, (errorCode, messageError) =>
{
//Log error
});
* Manage subscription
To manage the device subscription to one or more groups, there are two methods: topicsSubscribe and topicsUnsubscribe.
Optionally, both receive a TopicsCallback object as the third parameter, which will return the list of all Topic in the project.
//topics typeof string[]
indigitall.TopicsSubscribe(topics, (topic) =>
{
//DO SOMETHING
}, (errorCode, messageError) =>
{
//Log error
});
indigitall.TopicsUnsubscribe(topics }, (topic) =>
{
//DO SOMETHING
}, (errorCode, messageError) =>
{
//Log error
});
Collection of push data
In the event that you want to obtain the push object of type json to perform checks and / or when the user clicks on the notification and it is with the action of open app, we leave you this code that will help to obtain it:
- Set the default Activity
The Activity by default is the initial screen of your app that is launched when a user clicks on a notification that does not have a deeplink. It is also the point where you should initialize the SDK. It is set by the parameter DefaultActivity:
//When you want to start indigitall
Com.Indigitall.Android.Push.IndigitallPush.SetDefaultActivity(this, Java.Lang.Class.FromType(typeof("YOUR_ACTIVITY")).Name);
//or also
Com.Indigitall.Xamarin.Models.IConfiguration config = new Com.Indigitall.Xamarin.Models.IConfiguration();
config.appKey = "<YOUR-APP-KEY>";
config.senderId = "<YOUR-SENDER-ID>";
config.defaultActivity = Java.Lang.Class.FromType(typeof(MainActivity)).Name;
indigitall.Init(config)
In the case of Android we must add this code in the MainActivity and parse it as a push object to obtain the information:
var pushExtra = Com.Indigitall.Android.Push.Models.Push.ExtraPush;
if (Intent != null && Intent.GetStringExtra(pushExtra) != null)
{
Com.Indigitall.Android.Push.Models.Push push = new Com.Indigitall.Android.Push.Models.Push(Intent.GetStringExtra(pushExtra));
Console.WriteLine("Push object: ", push);
}
If you decide to treat the Push action independently without going through our SDK, in order to record the statistics you must do the following depending on the platform.
In the case of Android, the intent of the action is collected in your activity where the ServiceUtils.RegisterStatistics method should be called. For this case, you can, for example, create a class that extends from our PushNotification to generate the intent with the following extras:
public class PushNotification : Com.Indigitall.Android.Push.Models.PushNotification
{
Push push;
Context context;
public PushNotification(Push push): base(push)
{
this.push = push;
}
public override void ShowNotification(Context context)
{
this.context = context;
base.ShowNotification(context);
}
protected override PendingIntent GetIntent(PushAction action, int clickedButton){
Intent intent = action.GetIntent(context);
Intent indigitallIntent;
indigitallIntent = new Intent(context, typeof(MainActivity));
indigitallIntent.SetFlags(ActivityFlags.NewTask);
indigitallIntent.PutExtra(Com.Indigitall.Android.Push.Services.StatisticService.ExtraAppKey, Com.Indigitall.Android.Commons.Utils.PreferenceUtils.GetAppKey(context));
indigitallIntent.PutExtra(Com.Indigitall.Android.Push.Services.StatisticService.ExtraPushId, push.Id);
indigitallIntent.PutExtra(Com.Indigitall.Android.Push.Services.StatisticService.ExtraClickedButton, clickedButton);
indigitallIntent.PutExtra(Com.Indigitall.Android.Push.Services.StatisticService.ExtraIntentAction, intent);
indigitallIntent.PutExtra(Push.ExtraPush, push.ToString());
if (action.GetTopics() != null && action.GetTopics().Length > 0)
{
indigitallIntent.PutExtra(Com.Indigitall.Android.Services.Push.StatisticService.ExtraActionTopics, action.TopicsToString());
}
TaskStackBuilder stackBuilder = TaskStackBuilder.Create(context);
stackBuilder.AddNextIntentWithParentStack(indigitallIntent);
return stackBuilder.GetPendingIntent((push.Id * 10) + clickedButton,
PendingIntentFlags.OneShot);
}
Once the push has been collected, as explained in the previous section, the following method must be called to register statistics:
Com.Indigitall.Android.Push.Utils.ServiceUtils.RegisterStatistics(context, indigitallIntent);
In the case of iOS we must add this code in the AppDelegate of the application, both in the DidReceiveRemoteNotification method for the main action, and for the HandleAction method for the button action:
//class extends UNUserNotificationCenterDelegate
[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public override void DidReceiveNotificationResponse(UserNotifications.UNUserNotificationCenter center, UserNotifications.UNNotificationResponse response, Action completionHandler)
{
IndigitallXamarin.Indigitall.HandleWithResponse(response, (push, action) =>
{
Console.WriteLine("DidReceiveNotificationResponse push: " + push);
Console.WriteLine("DidReceiveNotificationResponse action: " + action.App);
});
}
//DidReceiveRemoteNotification
Com.Indigitall.Xamarin.iOS.Indigitall.HandleActionPush(userInfo, null, (push, action) => {
Console.WriteLine("DidReceiveRemoteNotification push: " + push);
Console.WriteLine("DidReceiveRemoteNotification action: " + action.app);
});
//HandleAction
Com.Indigitall.Xamarin.iOS.Indigitall.HandleActionPush(remoteNotificationInfo, actionIdentifier, (push, action) => {
Console.WriteLine("HandleAction push: " + push);
Console.WriteLine("HandleAction action: " + action.app);
});
If you decide to treat the Push action independently without going through our SDK, in order to record the statistics you must do the following depending on the platform.
In the case of iOS in the userNotificationCenter: didReceive method of the AppDelegate itself, in order to record the statistics, the following method must be added:
IndigitallXamarin.Indigitall.RegisterStatistics(response);
Push Secure Received Event - iOS platform
On Android is implemented into native sdk, but on iOS you have to add code.
Only on API use of Push Secure Sending
If you want to receive an event that indicate if the push comes with sendEventAck flag and the encrypted pushes are active, add the following on AppDelegate on didReceived method:
[Export("application:didReceiveRemoteNotification:fetchCompletionHandler:")]
override public void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
IndigitallXamarin.Indigitall.DidReceivePushWithNotification(userInfo, (push) =>
{
Console.WriteLine("Es una push secure");
});
}
Custom Push Notification Sounds (Xamarin.Android)
By default, push notifications use the system’s default sound. You can customize this behavior by assigning a specific audio file to a notification channel.
When to Consider a Custom Sound
A unique sound may help highlight certain notifications, such as:
- Urgent alerts that require immediate attention.
- Differentiating between notification categories (e.g., system vs. promotional).
- Reinforcing a branded experience.
Custom sounds can sometimes feel intrusive or disruptive for users, especially if they are loud, long, or significantly different from system defaults. In many cases, sticking to the system sound provides a more consistent and user-friendly experience.
Adding a Custom Sound File
To use a custom sound:
- Place your audio file (e.g., alert.mp3) inside the Resources/raw/ folder of your Xamarin.Android project.
Example path: MyApp/Resources/raw/alert.mp3
- File names must be lowercase and should not contain spaces or special characters.
Implementing in Code
When creating a NotificationChannel (required for Android 8.0 / API level 26 and above), you can assign your custom sound:
using Android.App;
using Android.Content;
using Android.Media;
using Android.Net;
using Android.OS;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
var notificationManager =
(NotificationManager)GetSystemService(Context.NotificationService);
var channel = new NotificationChannel(
"default", // Channel ID
"CHANNEL_NAME", // Channel Name (visible to the user)
NotificationImportance.High
);
var soundUri = Uri.Parse($"{ContentResolver.SchemeAndroidResource}://{PackageName}/{Resource.Raw.alert}");
var audioAttributes = new AudioAttributes.Builder()
.SetContentType(AudioContentType.Sonification)
.SetUsage(AudioUsageKind.Notification)
.Build();
channel.SetSound(soundUri, audioAttributes);
notificationManager.CreateNotificationChannel(channel);
}
}
Important Notes
- Custom sounds are tied to the notification channel. Once created, its sound cannot be changed; you must create a new channel with a different ID.
- Sounds should be short and subtle; long or loud sounds risk being perceived as annoying.
- On devices below Android 8.0 (Oreo), custom sounds can still be used, but without NotificationChannel.
Custom Push Notification Sounds (Xamarin.iOS)
By default, iOS notifications play the system sound. You can customize this by providing your own audio file and configuring it in the Notification Service Extension.
Adding a Custom Sound File
- Add your sound file (.caf, .aiff, or .wav) to the root of your Notification Service Extension project.
Example: MyAppNotificationExtension/alert.caf
- Ensure the file is included in the Bundle Resources (set Build Action to BundleResource).
- File names are case-sensitive and must match exactly what you reference in code.
Implementing in Code
In your NotificationService.cs file:
using System;
using UserNotifications;
public class NotificationService : UNNotificationServiceExtension
{
UNNotificationContent bestAttemptContent;
UNNotificationRequest request;
Action<UNNotificationContent> contentHandler;
public override void DidReceiveNotificationRequest(
UNNotificationRequest request,
Action<UNNotificationContent> contentHandler)
{
this.contentHandler = contentHandler;
bestAttemptContent = (UNMutableNotificationContent)request.Content.MutableCopy();
// Set custom sound
bestAttemptContent.Sound = UNNotificationSound.GetSound("alert.caf");
// Create a new request with updated content
this.request = UNNotificationRequest.FromIdentifier(
request.Identifier,
bestAttemptContent,
request.Trigger
);
// Pass to your SDK or process as needed
Indigitall.DidReceiveNotificationRequest(this.request, this.contentHandler);
}
public override void TimeWillExpire()
{
// Fallback if extension is about to expire
if (contentHandler != null && bestAttemptContent != null)
{
contentHandler(bestAttemptContent);
}
}
}