SDK

Device Registration

In this guide we will dive deeper into how you should handle the device registration. If you are using the default re.notifica.app.DefaultIntentReceiver, this will be done automatically for you. It is recommended that you implement you own Intent Receiver in order to gain control over the device registration.

As explained in the Implementation page, in your own Intent Receiver you will be overriding the onReady method. This method is called when the SDK has loaded correctly and the device is correctly registered to Notificare. A new device is always registered as a non-push device, so to receive notifications, you first have to enable them somewhere in your onboarding process.

The onReady method will also be called if your app was launched in the background, so you need to make sure you enable notifications if needed, like so:

public class MyIntentReceiver extends DefaultIntentReceiver {

    @Override
    public void onReady() {
        // Check if user allowed push before and enable push notifications for this device
        // You can leave out this check if you always want the app to receive push notifications
        if (Notificare.shared().isNotificationsEnabled()) {
            Notificare.shared().enableNotifications();
        }
    }

    //more code ...
}
class MyIntentReceiver : DefaultIntentReceiver() {
    override fun onReady() {
        // Check if user allowed push before and enable push notifications for this device
        // You can leave out this check if you always want the app to receive push notifications
        if (Notificare.shared().isNotificationsEnabled) {
            Notificare.shared().enableNotifications()
        }
    }
}

In this example, you still need to explicitly enable notifications at least once. For example if your app has an initial on-boarding process, you might not want to enable notifications until the user actually goes through these screens and lands in your first activity or fragment.

public class MyOnboardingActivity extends AppCompatActivity implements Notificare.OnNotificareReadyListener {

    //...more code

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Notificare.shared().addNotificareReadyListener(this);

        mEnableButton = rootView.findViewById(R.id.enableButton);
        mEnableButton.setOnClickListener(view -> {
            Notificare.shared().enableNotifications();
        });

    }


    @Override
    public void onNotificareReady(NotificareApplicationInfo notificareApplicationInfo) {

        // Enable the button only when Notificare is ready
        mEnableButton.setEnabled(true);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        Notificare.shared().removeNotificareReadyListener(this);
    }
}
class MyOnboardingActivity : AppCompatActivity(), OnNotificareReadyListener {

    //...more code

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Notificare.shared().addNotificareReadyListener(this)
        mEnableButton = rootView!!.findViewById(R.id.enableButton)
        mEnableButton.setOnClickListener(View.OnClickListener { view: View? ->
            Notificare.shared().enableNotifications()
        })
    }

    override fun onNotificareReady(notificareApplicationInfo: NotificareApplicationInfo) {

        // Enable the button only when Notificare is ready
        mEnableButton!!.isEnabled = true
    }

    override fun onDestroy() {
        super.onDestroy()
        Notificare.shared().removeNotificareReadyListener(this)
    }
}

Whenever you invoke the Notificare.shared().enableNotifications() method, our library will register the device for push enabled. It will also call the onDeviceRegistered method so you can listen to these registration events

public class MyIntentReceiver extends DefaultIntentReceiver {

    //...more code

    @Override
    public void onDeviceRegistered(NotificareDevice device) {
        // handle device, store it in your app, update UI to reflect push status, etc.
    }

    //...more code

}
class MyIntentReceiver : DefaultIntentReceiver() {

    //...more code

    override fun onDeviceRegistered(device: NotificareDevice) {
        // handle device, store it in your app, update UI to reflect push status, etc.
    }

    //...more code

}

You can always ask for the currently registered device

Notificare.shared().getRegisteredDevice();
Notificare.shared().registeredDevice

Check if push notifications are enabled

Notificare.shared().isNotificationsEnabled();
Notificare.shared().isNotificationsEnabled

And if the user has notifications enabled for this app in the device's settings

Notificare.shared().checkAllowedUI();
Notificare.shared().checkAllowedUI()

If you want to also give access to your app's settings view from the notification settings in the device's settings, you can listen to the NOTIFICATION_PREFERENCES intent. This will add a link to your activity inside the device's settings.

<activity android:name=".SettingsActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.NOTIFICATION_PREFERENCES" />
    </intent-filter>
</activity>

notification settings activity link

Register as a user

By default, a device is registered as an anonymous user. But there will be situations where simply registering an anonymous device is not what you want. For example if you authenticate your users you will not want to register an anonymous device whenever the app launches. When that is the case, you will need to tell the library you want to register as a specific user.

Notificare.shared().setUserId("123456789");
Notificare.shared().setUserName("John Doe");
Notificare.shared().registerDevice(new NotificareCallback<String>() {
    @Override
    public void onSuccess(String result) {
        //Handle Success
    }

    @Override
    public void onError(NotificareError error) {
        //Handle Error
    }
});
Notificare.shared().userId = "123456789"
Notificare.shared().userName = "John Doe"
Notificare.shared().registerDevice(object : NotificareCallback<String?> {
    override fun onSuccess(result: String?) {
        //Handle Success
    }

    override fun onError(error: NotificareError) {
        //Handle Error
    }
})

After that, the device will remain registered as that userId / userName until you explicitly register it as anonymous. Depending on the way you authenticate users, you might want to check the logged in state on launch (in the onReady) and change if necessary. Forcing registration as anonymous can be best achieved by setting userId and userName to null.

Notificare.shared().setUserId(null);
Notificare.shared().setUserName(null);
Notificare.shared().registerDevice(new NotificareCallback<String>() {
    @Override
    public void onSuccess(String result) {
        //Handle Success
    }

    @Override
    public void onError(NotificareError error) {
        //Handle Error
    }
});
Notificare.shared().userId = null
Notificare.shared().userName = null
Notificare.shared().registerDevice(object : NotificareCallback<String?> {
    override fun onSuccess(result: String?) {
        //Handle Success
    }

    override fun onError(error: NotificareError) {
        //Handle Error
    }
})

If you've followed these steps correctly and all the request succeeded, you should be able to see and send messages to devices/users via our dashboard and API.

Override Device Language

By default we will automatically collect the language and region of a device based on the Locale of the device. For most cases this will be enough but for those cases where you would like to override the device language and region combination to a strict selection of languages, you can do so by invoking the following method:

Notificare.shared().updatePreferredLanguage("en-US", new NotificareCallback<Boolean>() {
    @Override
    public void onSuccess(Boolean result) {

    }

    @Override
    public void onError(NotificareError notificareError) {

    }
});
Notificare.shared().updatePreferredLanguage("en-US", object : NotificareCallback<Boolean?> {
    override fun onSuccess(result: Boolean?) {}
    override fun onError(notificareError: NotificareError) {}
})

Eventually you can always retrieve the preferred language by calling the following method:

Notificare.shared().getPreferredLanguage();
Notificare.shared().preferredLanguage

As a convenience, you can also retrieve the current language (either the device locale or the preferred language, if set) by calling

Notificare.shared().getCurrentFullLanguage();
Notificare.shared().currentFullLanguage

User Data Fields

There are use cases where simply associating an userID and userName will not suffice. For those cases you can make use of User Data Fields where you can create key-value pairs for your application and then use them to extend your device registration. Before you can implement them you will need to first create them in your application via our dashboard. This is described here.

Once you have created one or more fields, you can implement this functionality in your app. To retrieve the list of fields allowed in your app you should use the following method:

Notificare.shared().fetchUserData(new NotificareCallback<NotificareUserData>() {
    @Override
    public void onSuccess(NotificareUserData notificareUserData) {
        //Handle the key-value pairs
    }

    @Override
    public void onError(NotificareError notificareError) {
        //Handle Error
    }
});
Notificare.shared().fetchUserData(object : NotificareCallback<NotificareUserData?> {
    override fun onSuccess(notificareUserData: NotificareUserData?) {
        //Handle the key-value pairs
    }

    override fun onError(notificareError: NotificareError) {
        //Handle Error
    }
})

Whenever you want to update those fields with new values you should use the following method:

Notificare.shared().updateUserData(notificareUserData, new NotificareCallback<Boolean>() {
    @Override
    public void onSuccess(Boolean aBoolean) {
        //Handle success
    }

    @Override
    public void onError(NotificareError notificareError) {
        //Handle error
    }
});
Notificare.shared().updateUserData(notificareUserData, object : NotificareCallback<Boolean?> {
    override fun onSuccess(aBoolean: Boolean?) {
        //Handle success
    }

    override fun onError(notificareError: NotificareError) {
        //Handle error
    }
})

If you are using our inbox functionality, these fields will also be available as placeholders when sending notifications by simply including {{userData.key}} in your messages.

Do Not Disturb

Each device registered with Notificare can be configured to specify a period of time during the day where it should not receive notifications. You can use this functionality in your app settings view to allow the user to provide a time range where messages will not be displayed in the lock screen or notification center. Please note that if you are using our inbox functionality these message will still be there.

To retrieve a device's DnD preferences use the following method:

Notificare.shared().fetchDoNotDisturb(new NotificareCallback<NotificareTimeOfDayRange>() {
    @Override
    public void onSuccess(NotificareTimeOfDayRange notificareTimeOfDayRange) {
        //Handle success
    }

    @Override
    public void onError(NotificareError notificareError) {
        //Handle error
    }
});
Notificare.shared().fetchDoNotDisturb(object : NotificareCallback<NotificareTimeOfDayRange?> {
    override fun onSuccess(notificareTimeOfDayRange: NotificareTimeOfDayRange?) {
        //Handle success
    }

    override fun onError(notificareError: NotificareError) {
        //Handle error
    }
})

You can update the DnD values for a device, using the following method:

Notificare.shared().updateDoNotDisturb((NotificareTimeOfDayRange) range, new NotificareCallback<Boolean>() {
    @Override
    public void onSuccess(Boolean aBoolean) {
        //Handle success
    }

    @Override
    public void onError(NotificareError notificareError) {
        //Handle error
    }
});
Notificare.shared().updateDoNotDisturb(range, object : NotificareCallback<Boolean?> {
    override fun onSuccess(aBoolean: Boolean?) {
        //Handle success
    }

    override fun onError(notificareError: NotificareError) {
        //Handle error
    }
})

Test Devices

In SDK 2.6 and higher, it is possible to enable devices to be registered as test devices. This allows you to perform a wide range of tests in our dashboard by simply scanning a QR Code. In order to enable this functionality, the following steps are mandatory.

First you need to add the following URL scheme to your app's AndroidManifest.xml:

<activity android:name=".MainActivity">

    <!-- ... existing intent filters    -->

    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <!-- ... existing schemes   -->

        <data android:scheme="test.nc${notificareAppId}" />

    </intent-filter>

</activity>

Where {notificareAppId} must be replaced by your own app identifier (you can find that in Settings > Configure App).

Then inside the intent handling routine in your MainActivity, you will need to handle possible intents to that URL scheme

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    handleIntent(getIntent());
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    handleIntent(intent);
}

void handleIntent(Intent intent) {
    if (Notificare.shared().handleTestDeviceIntent(intent)) {
        Log.d(TAG, "test device intent handled");
    } else {
        // your normal intent handling routine
    }
}
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    handleIntent(intent)
}

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    handleIntent(intent)
}

fun handleIntent(intent: Intent?) {
    if (Notificare.shared().handleTestDeviceIntent(intent) {
        Log.d(TAG, "test device intent handled");
    } else {
        // your normal intent handling routine
    }
}

The method will return true if the intent could be parsed as a Test Device registration intent. If it returns false, this means you should process the intent yourself.

Disable Notifications

Pretty much the same way you enable notifications you will also disabled them. To do that, use the following method:

Notificare.shared().disableNotifications();
Notificare.shared().disableNotifications()

When this method is called, we will automatically register your device to never receive remote notifications, although you will still maintain the same user profile, inbox messages and enjoy all the other services your plan supports. You can at anytime request a re-register for push notifications if you wish to.

Un-launch Notificare

Finally, it is also possible to completely remove all data for a device, both locally in your app and remotely in our servers. To do that, use the following method:

Notificare.shared().unlaunch();
Notificare.shared().unlaunch()
After invoking this, all the device's data will be destroyed and cannot be undone. Also, invoking any other method in Notificare will fail and the only way to start using the SDK again, is by invoking its counterpart, the ```launch``` method.