Google Play services

Introduction

Set up Google Play services by following Google’s official instructions.

Include infobip-push-<version>.jar in your Android project’s /libs/ folder. Add jar file to project’s build path.

To use the Infobip Push library, set the minimal required SDK to version 8. Push notifications are supported from that version of Android OS. Use any version greater or equal to 8 as the target version.

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="xy" />

Permissions

Declare custom permission so that only your application can receive your push notifications. Permission must be called “your_package_name.permission.C2D_MESSAGE” where “your_package_name” is the name of application package you declared in the AndroidManifest.xml.

<permission
    android:name="your_package_name.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

Add the following required permissions:

<uses-permission android:name="your_package_name.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

If you’re going to use built-in message handling, it is recommended to add the following permission:

<!-- Needed for push notifications that contain VIBRATE flag. Optional, but recommended. -->
<uses-permission android:name="android.permission.VIBRATE" />

Internal receivers and a service

Push library requires the following items to be defined inside the <application> tag:

<service android:name="com.infobip.push.lib.InfobipPushService"/>

<receiver android:name="com.infobip.push.lib.InternalReceiver" />

<receiver android:name="com.infobip.push.lib.InfobipPushReceiver"
           android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
        <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
        <category android:name="your_package_name"/>
    </intent-filter>
</receiver>

Meta-data tag

Add meta-data tag for Push library to know which Google Play services version user’s application has.

<meta-data
    android:name="com.google.android.gms.version"
    android:value="@+integer/google_play_services_version" />

Receiving notifications

To receive notifications, define a broadcast receiver in the AndroidManifest.xml:

<receiver android:name=".MyPushReceiver"
    android:permission="your_package_name.permission.C2D_MESSAGE">
    <intent-filter>
        <action android:name="com.infobip.push.intent.REGISTERED_FOR_NOTIFICATIONS"/>
        <action android:name="com.infobip.push.intent.REGISTRATION_REFRESHED"/>
        <action android:name="com.infobip.push.intent.UNREGISTERED_FROM_NOTIFICATIONS"/>
        <action android:name="com.infobip.push.intent.NOTIFICATION_RECEIVED"/>
        <action android:name="com.infobip.push.intent.NOTIFICATION_OPENED"/>
        <action android:name="com.infobip.push.intent.ERROR"/>

        <category android:name="your_package_name"/>
    </intent-filter>
</receiver>

BroadcastReceiver class should extend AbstractPushReceiver. All push notification related events are fired via appropriate events.

public class MyPushReceiver extends AbstractPushReceiver {

    @Override
    public void onRegistered(Context context) {  }

    @Override
    protected void onRegistrationRefreshed(Context context) {  }

    @Override
    public void onNotificationReceived(PushNotification notification, Context context) {  }

    @Override
    protected void onNotificationOpened(PushNotification notification, Context context) {  }

    @Override
    public void onUnregistered(Context context) {  }

    @Override
    public void onError(int reason, Context context) {  }
}

Initial setup

To setup library for push notifications, use the sender ID (your Google Project number) obtained from the Google API Console along with the application ID and application secret obtained from http://push.infobip.com.

private PushNotificationManager manager;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    manager = new PushNotificationManager(this);
    manager.setDebugModeEnabled(true); //Enable debug mode to view log
    manager.initialize("<senderId>", "<applicationId>", "<applicationSecret>");
}

Registering for push notifications

User registration is required to receive push notifications (otherwise, no notification will be received):

manager.register(); //manager is a PushNotificationManager instance instantiated in onCreate()

After successful registration, AbstractPushReceiver.onRegistered(Context) will be called. If an error occurs, AbstractPushReceiver.onError(int, Context) will be called.

Android library guide

Required Android SDK packages installed:

  • Google APIs + SDK Platform – minimum API 8
  • Google Cloud Messaging for Android Library – used for receiving push notifications
  • Google Play services – used for managing live geo feature (in future will be used for receiving push)

Optional Android SDK package:

  • Google Play services for Froyo – used for managing live geo feature on Froyo devices

Project setup

Download our Android Push library from here. In order to properly configure your project for receiving push notifications you will primarily need to include it into your project, set up your AndroidManifest.xml file and initialize the obtained data.

As of release 1.3.0, Android Push library requires Google Play services library project, so you’ll need to set it up by following Google’s official instructions.

Include Infobip Push library into your project

Copy infobip-push-<version>.jar to your Android project’s /libs/ folder. Right click the name of the library and add jar file to project’s build path.

Including Infobip Push library
Including Infobip Push library

Android manifest file

Since GCM push notifications are supported from Android API 8, set minimal required SDK version to 8. Use any version greater or equal to 8 as the target version.

The following receivers and services are required for setting up your AndroidManifest.xml file: InfobipPushService, InfobipPushReceiver, InternalReceiver and your broadcast receiver defined with the required actions. You will also need to include the Internet and GCM permissions, along with the meta-data tag for Google Play services.

Below is an example of the default AndroidManifest.xml file with permissions, receivers and services you will need to define clearly highlighted. Copy them to your manifest file. You must insert the name of your applications package in the places with highlighted package name, eg. "your_package_name".

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your_package_name"
    android:versionCode="1"
    android:versionName="1.0" >

<!-- Set minimal required SDK version to 8 since GCM push is enabled from that Android OS version. Use any version greater or equal to 8 as the target version. -->
<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />

<!-- REQUIRED PERMISSIONS -->
<!-- Custom permission declared so that only your application can receive your notifications. -->
<permission
    android:name="your_package_name.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

<!-- Previously custom defined permission -->
<uses-permission android:name="your_package_name.permission.C2D_MESSAGE" />
<!-- Permission to receive push notifications -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Connect to the Infobip Push service -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Using push notifications requires a Google account -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Checks network state -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- REQUIRED PERMISSIONS -->

<!-- OPTIONAL PERMISSIONS -->
<!-- Needed for push notifications that contain VIBRATE flag. Optional, but recommended. -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- OPTIONAL PERMISSIONS -->

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >

    <activity
        android:name=".MainActivity"
        android:label="@string/title_activity_main" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <!-- REQUIRED SERVICES -->
    <service android:name="com.infobip.push.lib.InfobipPushService"/>
    <!-- REQUIRED SERVICES -->

    <!-- REQUIRED RECEIVERS -->
    <receiver android:name="com.infobip.push.lib.InfobipPushReceiver"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
            <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
            <category android:name="your_package_name"/>
        </intent-filter>
    </receiver>

    <receiver android:name="com.infobip.push.lib.InternalReceiver" />

    <receiver android:name=".MyPushReceiver"
        android:permission="your_package_name.permission.C2D_MESSAGE">
        <intent-filter>
            <action android:name="com.infobip.push.intent.REGISTERED_FOR_NOTIFICATIONS"/>
            <action android:name="com.infobip.push.intent.REGISTRATION_REFRESHED"/>
            <action android:name="com.infobip.push.intent.UNREGISTERED_FROM_NOTIFICATIONS"/>
            <action android:name="com.infobip.push.intent.NOTIFICATION_RECEIVED"/>
            <action android:name="com.infobip.push.intent.NOTIFICATION_OPENED"/>
            <action android:name="com.infobip.push.intent.ERROR"/>

            <category android:name="your_package_name"/>
        </intent-filter>
    </receiver>
    <!-- REQUIRED RECEIVERS -->

    <!-- REQUIRED METADATA TAG -->
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@+integer/google_play_services_version" />
    <!-- REQUIRED METADATA TAG -->

</application>

Check manifest

To make sure that nothing required is missing in your Android manifest file, use PushNotificationManager.checkManifest() method. Any error will be logged, so please check your LogCat to verify that manifest is properly configured.

Note: Debug mode has to be enabled to view log. Check if it’s enabled by using PushNotificationManager.isDebugModeEnabled()method.

Receiving notifications

Create new class (named MyPushReceiver in this example) and extend a broadcast receiver class called AbstractPushReceiver from the Push library. All push notification related events are fired via appropriate events.

public class MyPushReceiver extends AbstractPushReceiver {

    @Override
    public void onRegistered(Context context) {
        Toast.makeText(context, "Successfully registered.", Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onRegistrationRefreshed(Context context) {
        Toast.makeText(context, "Registration is refreshed.", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onNotificationReceived(PushNotification notification, Context context) {
        Toast.makeText(context, "Received notification: " + notification.toString(), 
             Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onNotificationOpened(PushNotification notification, Context context) {
        Toast.makeText(context, "Notification opened.", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onUnregistered(Context context) {
        Toast.makeText(context, "Successfully unregistered.", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onError(int reason, Context context) {
        Toast.makeText(context, "Error occurred: " + reason, Toast.LENGTH_SHORT).show();
    }
}

Alternatively, you can register the broadcast receiver in your Activity class for foreground usage only (without using manifest):

//Declare push receiver
private BroadcastReceiver receiver = new AbstractPushReceiver() {

    @Override
    public void onRegistered(Context context) { }

    @Override
    public void onUnregistered(Context context) { }

    @Override
    public void onNotificationReceived(PushNotification notification, Context context) { }

    @Override
    public void onError(int reason, Context context) { }
};

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

    IntentFilter filter = new IntentFilter();
    filter.addAction("com.infobip.push.intent.REGISTERED_FOR_NOTIFICATIONS");
    filter.addAction("com.infobip.push.intent.REGISTRATION_REFRESHED");
    filter.addAction("com.infobip.push.intent.UNREGISTERED_FROM_NOTIFICATIONS");
    filter.addAction("com.infobip.push.intent.NOTIFICATION_RECEIVED");
    filter.addAction("com.infobip.push.intent.NOTIFICATION_OPENED");
    filter.addAction("com.infobip.push.intent.ERROR");
    filter.addCategory(getPackageName());

    registerReceiver(receiver, filter); //Register receiver
}

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(receiver); //Unregister receiver
}

Initialize your application

To setup library for push notifications, use the sender ID obtained from the Google API Console (your Google Project number), along with the application ID and application secret obtained from http://push.infobip.com. Library’s initialization is performed with PushNotificationManager.initialize(String, String, String) method. When you call it, it manages user’s time zone changes and generates user’s own device ID that will uniqely identify him/her in the Infobip Push system.

As of 1.2.0 release, library’s initialization prevents GCM registration exipry, since Google stated that it could be invalidated when your application version changes.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    PushNotificationManager manager = new PushNotificationManager(this);
    manager.initialize("<senderId>", "<applicationId>", "<applicationSecret>");
}

Registering for Infobip Push

To receive push notifications, user registration is required. Use PushNotificationManager.register() method for user registration which will register your user’s device ID.

If you want to provide user related data, such as user ID or channels, use PushNotificationManager.register(RegistrationData) method to register your user.

When the registration succeeds intent with the “com.infobip.push.intent.REGISTERED_FOR_NOTIFICATIONS” action will be invoked. It executes AbstractPushReceiver.onRegistered(Context) method which you can implement your code in after successful registration. If an error occurs, AbstractPushReceiver.onError(int, Context) will be called.

Unregistering from Infobip Push

To stop receiving push notifications, application should invoke PushNotificationManager.unregister() method. Upon successful unregistration, AbstractPushReceiver.onUnregistered(Context) will be called. If an error occurs, AbstractPushReceiver.onError(int, Context) will be called.

Once unregistered you won’t be able to receive notifications anymore, and user related data will be deleted, however, the initialized application data (sender ID, application ID and application secret) will remain.

Note: If you call PushNotificationManager.isRegistered() method right after calling PushNotificationManager.unregister(), it will probably return true (meaning your user is still registered) because unregistration hasn’t finished yet. If you need to check when the unregistration process has been finished, register AbstractPushReceiver dynamically in your activity.

User management

There are two ways of providing user related data to the Infobip Push service:

  1. When registering for push, you can provide a user ID, phone number and the channel list in RegistrationData for distinguishing your users. Timezone offset and device ID will also be transmitted to Infobip Push. After unregistration, user related data you provided are deleted from the library.
private PushNotificationManager manager; //Instantiated in onCreate()

public void onSubscriptionClick(View v) {
    String userID = "<some- user-id>";
    String phoneNumber = "385951112222";
    List channels = new ArrayList();
    channels.add("sport");
    channels.add("news");
    channels.add("weather");

    //Perform registration
    RegistrationData registrationData = new RegistrationData();
    registrationData.setUserId(userID);
    registrationData.setPhoneNumber(phoneNumber);
    registrationData.setChannels(channels);
    manager.register(registrationData); //registrationData is optional
}
  1. When your user is already registered for push, you can change his data from your code at any time.

UserID

Setting up user’s ID lets you generate IDs that you find meaningful for your application. These ID’s don’t need to be unique. There are two states in which you can provide userId to Infobip Push service:

  1. On the first registration for push, set userId with RegistrationData.setUserId(String) method and call PushNotificationManager.register(RegistrationData).
  2. Call PushNotificationManager.saveNewUserId(String, UserDataListener) at any time if the user is registered for push.

DeviceID

Device ID is a field that uniqely identifies your user in the Infobip Push system. It is generated only once by the Push library – the first time you call PushNotificationManager.initialize(String, String, String) method. You can use it to send push notifications to a specific user after your user is registered for Push. Get user’s deviceId using following method:

PushNotificationManager manager = new PushNotificationManager(context);
String deviceId = manager.getDeviceId();

Note: Device ID may be deleted if your user clears application data. In that case, new device ID is generated by the library.

Timezone offset

Automatic timezone offset updates are enabled by default. The value of the timezone offset is the actual offset from UTC for a given point in time defined in minutes. The offset includes daylight savings time if the specified date is within the daylight savings time period. Make use of the timezone offset when sending a scheduled notification in a specific time to target each user by the timezone he is in.

However, if you want to manually set an offset from UTC for the time zone, use PushNotificationManager.setTimeZoneOffset(int minutes). Manually setting the time zone disables automatic checks and updates of the time zone changes.

Switch between automatic and manual time zone updates with PushNotificationManager.setTimeZoneAutomaticUpdateEnabled(boolean).

Phone number for SMS fallback

Enabling SMS fallback feature on your application’s side means providing user’s phone number to our library. Library will save it on the Infobip Push service. Phone number must include a country calling code (e.g. UK: 44, Croatia: 385), carrier’s mobile prefix (e.g. UK: 75 , Croatia: 95) and an actual phone number (e.g. 1234567). Complete valid phone number provided to Push library should look like this: (UK) 44751234567, (Croatia) 385951234567.

Phone number may contain only numbers with minimum length of 8 characters (including country calling code and carrier’s mobile prefix). No double zero prefix, pluses, spaces, dashes or parentheses are allowed. If we look at the example phone number from Croatia (385): +385 95 123 4567 which is the same as 00385 95 123 4567, then you should call method setPhoneNumber with phone number parameter as 385951234567.

Not registered user

For user who’s not yet registered for push, provide his phone number in user related data during initial registration for push. Use PushNotificationManager.register(RegistrationData data) method where you set phone number with data.setPhoneNumber(String).

Registered user

Set user’s phone number at any time when user is already registered by using RegistrationData.setPhoneNumber(String, UserDataListener). This will instantly save user’s phone number on the Infobip Push service.

Channels

Infobip Push library offers the way of connecting your user to corresponding channels (UTF-8 encoding supported).

Subscribe to channels

Not registered user

If the user is not yet registered for push notifications, subscribe him/her to channels providing user related data during the registration. Use PushNotificationManager.register(RegistrationData data) method where you set channels with data.setChannels(List<String> channels). Example is shown in “User managemenet” section.

Registered user

If the user is already registered, subscribe him/her to channels by using PushNotificationManager.registerToChannels(List<String> channels, boolean removeExistingChannels, ChannelRegistrationListener listener) method.

User will be registered to provided channels, with the new channels created on Infobip Push service if you haven’t already created them per application. Once you set removeExistingChannels variable to true, existing channels on the Push service will be deleted, and a list of new channels will replace them. If false, existing channels will stay intact and user will be registered to newly provided list of channels. Monitor channel registration success using ChannelRegistrationListener.

Get registered channels

Channels that you registered your user to are saved on the Infobip Push service. You can obtain them using PushNotificationManager.getRegisteredChannels(ChannelObtainListener) method.

Here’s an example:

manager.getRegisteredChannels(new ChannelObtainListener() {

    @Override
    public void onChannelsObtained(String[] channels) {
        for (String channel : channels) {
            Log.d("DemoApp", "Channel: " + channel);
        }
    }

    @Override
    public void onChannelObtainFailed(int reason) {

        switch (reason) {
        case ChannelObtainListener.LIBRARY_NOT_INITIALIZED:
        case ChannelObtainListener.USER_NOT_REGISTERED:
            Toast.makeText(getApplicationContext(), "User is not registered.", Toast.LENGTH_SHORT).show();
            break;

        case ChannelObtainListener.INTERNET_NOT_AVAILABLE:    
        case ChannelObtainListener.OPERATION_FAILED:
        case ChannelObtainListener.PUSH_SERVICE_NOT_AVAILABLE:
            Toast.makeText(getApplicationContext(), "Channel obtaining failed.", Toast.LENGTH_SHORT).show();
            break;
        }
    }
});

Unsubscribe from channels

If your user is registered to some channels, unsubscribe him/her from all the channels using PushNotificationManager.registerToChannels(List<String> channels, boolean removeExistingChannels, ChannelRegistrationListener listener) method with an empty list of channels and removeExistingChannels argument set to true.

Use it like this:

List<String> channels = new ArrayList<String>(); //Note that the channel list is empty

manager.registerToChannels(channels, true, new ChannelRegistrationListener() {

    @Override
    public void onChannelsRegistered() {
        //user is unregistered from all of the channels
    }

    @Override
    public void onChannelRegistrationFailed(int reason) {
       //channel registration failed
    }
});

Notification handling

Once registered, your user is able to receive notifications. When the notification is received, library creates an instance of PushNotification class which contains information about the received push, and invokes default action showing notification in the status bar and the notification drawer. Default message handling mechanism is customizable. For more details on customization, see section “Default action”.

If you want to build notifications on your own, override the default notification handling using PushNotificationManager.overrideDefaultMessageHandling(boolean) method.

PushNotification object

Received notification is represented by PushNotification object that contains information about the received push. You can retrieve it through your custom defined broadcast receiver with AbstractPushReceiver.onNotificationReceived(PushNotification, Context) and AbstractPushReceiver.onNotificationOpened(PushNotification, Context) methods. PushNotification instance contains following push fields: id, notificationId, mimeType, title, message, sound, vibrate, lights, url, additionalInfo and mediaData. Some of these fields may be empty if you haven’t sent them in your push payload.

Push notification’s id field contains the ID of the notification sent from the Push service. It is used for generating analytics about received/opened notifications.

notificationId field contains the ID that is used for building the notification by the library. It’s value equals -1 (unset) if the default notification handling is overriden. Using notificationId you can update the notification or cancel it.

Default action

Once the notification is received, default action is invoked. Default action means that the library takes care about displaying the notification. If you don’t customize it using PushNotificationBuilder class, it will be displayed like this:

Notification in statusbar
Notification in statusbar
Notification drawer
Notification drawer

Customize status bar notification

Notification in the status bar consists of the icon and the ticker text to be displayed. Also, corresponding actions can be performed while displaying the notification: sound, vibration, flashing lights.

Default:

icon android.R.drawable.ic_dialog_email from Android resources
ticker text The “title” that you’ve sent via REST API. If the title isn’t sent, “message” will be displayed as a ticker text.
sound unset
vibration unset
LED lights unset
sound to play (resource ID) mobile’s default setting
vibration pattern mobile’s default setting
LED light color mobile’s default setting
LED on/off mobile’s default setting

Status bar notification can be overriden by using PushNotificationBuilder class. Set your own icon providing resource’s drawable id, and ticker text providing the text you want to display. If you don’t want, e.g., user’s phone to vibrate override that action too.

PushNotificationBuilder builder = new PushNotificationBuilder(getApplicationContext());
builder.setIconDrawableId(R.drawable.app_icon);
builder.setTickerText("Sample ticker text.");
builder.setSoundResourceId(R.raw.my_sound);
builder.setVibration(PushNotificationBuilder.ENABLED);
builder.setVibrationPattern(new long[]{100, 200, 100, 300});
builder.setLightsOnOffMS(2000, 1000);
builder.setLightsColor(Color.WHITE);

Notes:

  • User’s phone won’t make sound if the default ringtone is silent.
  • User’s phone won’t vibrate if the vibration is turned off.
  • User’s phone won’t flash lights if the device doesn’t have LED lights.

Customize notification display in the notification drawer

For the notification drawer customization you will need to create your own layout to be used as a remote view. Right click your Android project’s /res/ folder and create new XML layout file.

Here’s an example of one:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/image"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:scaleType="centerInside"
        android:src="@drawable/ic_launcher" />

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@+id/image"
        android:padding="5dp" >

        <TextView
            android:id="@+id/title"
            style="@style/NotificationTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/date"
            android:ellipsize="marquee"
            android:layout_marginRight="7dp"
            android:singleLine="true"
            android:text="title" />

        <TextView
            android:id="@+id/text"
            style="@style/NotificationText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/title"
            android:layout_below="@+id/title"
            android:layout_marginRight="10dp"
            android:ellipsize="marquee"
            android:singleLine="true"
            android:text="text" />

        <TextView
            android:id="@+id/date"
            style="@style/NotificationText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:gravity="right"
            android:singleLine="true"
            android:text="22:11"
            android:textSize="15sp" />

    </RelativeLayout>

</RelativeLayout>

What you need to provide to PushNotificationBuilder instance are the resource IDs correlated with your remote view:

  • the resource ID of the layout file – PushNotificationBuilder.setLayoutId(int)
  • the resource ID of the image view – PushNotificationBuilder.setImageId(int)
  • the resource ID of a drawable to use as the image – PushNotificationBuilder.setImageDrawableId(int)
  • the resource ID of the ‘title’ view – PushNotificationBuilder.setTitleId(int)
  • the resource ID of the ‘text’ view – PushNotificationBuilder.setTextId(int)
  • the resource ID of the ‘date’ view – PushNotificationBuilder.setDateId(int)

The only ID that you must provide is the layout ID. If you don’t want to display some of these views, don’t provide their IDs, and their values won’t be set to your remote view.

Notification layout
Notification layout

Notification title and text style

Since API level 9, Android introduced built-in styles for notification layout text styling. However, if you’re building your application for minimum Android version 8, you will have to implement your own styles.

For our remote view layout example, we used NotificationTitle and NotificationText styles.

Right-click the /res/ folder and create values and values-v9 folders if you already don’t have them in your application. Create styles.xml file in each folder.

Copy these two styles to your styles.xml file located in values folder (OS version 2.3-):

<style name="NotificationText">
    <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
</style>

<style name="NotificationTitle">
    <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
    <item name="android:textStyle">bold</item>
</style>

Copy these two styles to your styles.xml located in values-v9 folder (OS version 2.3+):

<style name="NotificationText" parent="android:TextAppearance.StatusBar.EventContent" />
<style name="NotificationTitle" parent="android:TextAppearance.StatusBar.EventContent.Title" />

Quiet time

Provide your user the time when sound, vibration and flashing lights won’t perform by implementing the quiet time. Quiet time interval is set with the start hour, start minute, end hour, end minute parameters where hour is in 24-hour time format. Enable the quiet time if you want the library to take it into account.

builder.setQuietTimeEnabled(true); //builder is a PushNotificationBuilder instance
builder.setQuietTime(22, 00, 7, 00);

You can check if the quiet time is working if no sound, vibration or flashing LED lights are performed when the notification is received while the current time is in the quiet time interval.

Override the default notification handling

Use PushNotificationManager.overrideDefaultMessageHandling(boolean) to override the default message handling, where boolean value is set to true, as previously mentioned.

Overriding default notification handling means that:

  • the library won’t display the received notification
  • PushNotification instance passed in AbstractPushReceiver.onNotificationReceived(PushNotification, Context) method won’t contain notificationId field since the library doesn’t build the notification
  • AbstractPushReceiver.onNotificationOpened(PushNotification, Context) will never be called
  • to track the notification opened statistics you will have to manually call the PushNotificationManager.notifyNotificationOpened(int pushId, NotificationOpenedListener listener) method

Retrieving live geo notifications

Live geo notifications are managed in the same way like standard notifications. When the user enters/exits specified area, notification is triggered and you can retrieve it in AbstractPushReceiver.onNotificationReceived(Context, PushNotification) method. If user never enters the area, notification will never be triggered, and the area will be deleted once it expires.

Location

AndroidManifest.xml – permissions

These two permissions are needed for location and live geo related push notifications:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

AndroidManifest.xml – receivers and services

Add needed receivers and services inside <application> tag:

<!-- Required for managing location and live geo features after device rebooting. -->
<receiver android:name="com.infobip.push.lib.LocationBootReceiver" android:exported="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

<!-- Required for using the Infobip location service. Retrieves user's location. -->
<service android:name="com.infobip.push.lib.LocationService"/>
<!-- Required for using the location feature. Updates user's location to te Infobip Push service. -->
<service android:name="com.infobip.push.lib.LocationUpdateService"/>

<!-- Required for live geo feature. It takes care of daily scheduled requests for getting live geo areas if some of them weren't received during normal application workflow. -->
<receiver android:name="com.infobip.push.lib.livegeo.LiveGeoReceiver" android:exported="false">
    <intent-filter>
        <!-- used for covering marginal case scenarios when adding or removing areas failed (disabled providers) -->
        <action android:name="android.location.PROVIDERS_CHANGED"/>
    </intent-filter>
</receiver>

<!-- Required for live geo feature. Takes care of live geo transitions (enter/now/exit). -->
<service android:name="com.infobip.push.lib.livegeo.ReceiveTransitionsIntentService" />
<!-- Takes care of requesting, adding or removing areas -->
<service android:name="com.infobip.push.lib.livegeo.LiveGeoIntentService" />

Use Infobip location service

In Push library version 1.1.1 we introduced our own location service that acquires user’s latest location and sends it periodically to the Infobip Push service in the background. By using this service, your location can be retrieved with all the location providers: GPS, NETWORK or PASSIVE provider.

Add ACCESS_FINE_LOCATION permission for covering all providers. Push library will switch between them in an efficient way to provide the latest user location. Covering all providers increases location accuracy. Make sure that you’ve added "com.infobip.push.lib.LocationService" and "com.infobip.push.lib.LocationUpdateService" service, along with "com.infobip.push.lib.LocationBootReceiver" receiver to your AndroidManifest.xml file.

How to use it:

Start Push location service using PushLocationManager.enableLocation() to track user’s location and stop it with PushLocationManager.disableLocation() method. Once started, Push location service sends location updates to the Infobip Push service in the default interval, or in the interval specified using PushLocationManager.setLocationUpdateTimeInterval(int), where you define int value in minutes.

Use your own location service

In case you already implemented your own location service and you want to use it to provide location to the Infobip Push, you need to follow these steps:

  1. add "com.infobip.push.lib.LocationUpdateService" service, along with "com.infobip.push.lib.LocationBootReceiver" receiver to your AndroidManifest.xml file
  2. call PushLocationManager.useCustomLocationService(boolean) with the boolean being set to true
  3. set the location sending interval in minutes using PushLocationManager.setLocationUpdateTimeInterval(int) or the default one will be used
  4. enable location sending using PushLocationManager.enableLocation()
  5. call PushLocationManager.saveUserLocation(Location location) each time you want the library to save user’s location (only the last location will be sent to our servers in the specified interval)
  6. disable sending location with PushLocationManager.disableLocation()

Keep in mind that Push library takes care of location sending, and that you cannot send it instantly. It is being sent in the background in the default or the specified interval.

Live geo management

Since Push library version 1.3.0 we support managing live geo notifications. Live geo support is disabled by default.

For the implementation of this feature, Google’s Geofencing API was used, so it requires Google Play services to be referenced as a library project. However, if you want to develop for Froyo devices, you will need to include Google Play services for Froyo package. Add ACCESS_FINE_LOCATION permission and make sure that you’ve added "com.infobip.push.lib.LocationBootReceiver", "com.infobip.push.lib.livegeo.LiveGeoReceiver", "com.infobip.push.lib.livegeo.ReceiveTransitionsIntentService" and "com.infobip.push.lib.livegeo.LiveGeoIntentService" to you manifest file.

Enabling live geo feature will start listening for live geo notifications and schedule their daily sync. You can enable it using a method:

PushLocationManager locManager = new PushLocationManager(context);
locManager.enableLiveGeo() //enables live geo

For disabling live geo use PushLocationManager.disableLiveGeo() method which will stop monitoring all live geo areas and cancel daily live geos sync.

Check at any time the number of active live geo areas for a particular user by calling the method PushLocationManager.getActiveLiveGeoAreasNumber(). You can stop monitoring all active live geo areas with PushLocationManager.stopMonitoringLiveGeoAreas() method. Once you stop their monitoring, those areas are cleared and you cannot start monitoring them again. Method returns the number of stopped live geo areas:

int stoppedAreasCount = locManager.stopMonitoringLiveGeoAreas();

Media push

Media push stands for the media content sent within a payload of your push notification. Media content referes to a multimedia content (text, images, video, audio) wrapped inside HTML tags. Since 1.2.0 version, Android Push library provides MediaWebView and MediaActivity that will help you in media content managing.

Media Web View

MediaWebView is a subclass of the WebView and thereby inherits its methods, fields and default configuration. Additionally, MediaWebView configuration has zoom controls, JavaScript, plugins, file and content access enabled by default, along with WebViewClient and WebChromeClient. Links which are clicked inside this view will be opened in the same view.

Usage of the MediaWebView is the same as the usage of the Android’s default WebView. You can add it as an element to activity’s layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.infobip.push.media.MediaWebView
        android:id="@+id/mediaView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

or set it directly as an activity’s content view in activity’s onCreate() method:

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

    MediaWebView mediaView = new MediaWebView(this);
    setContentView(mediaView);
}

For loading media data use MediaWebView.loadMediaData(String mediaContent) or for loading URL call MediaWebView.loadMediaUrl(String mediaUrl). These methods can be called from within activity’s onCreate() method. Follow Google’s official WebView documentation for supporting different screen densities: http://developer.android.com/reference/android/webkit/WebView.html.

Media Activity

Media activity is intended to help you in displaying the content of the media data. It uses MediaWebView in its implementation, which means that the default settings from MediaWebView also apply to this activity. In case you have special requirements for displaying media data, you can always implement your own way of handling this.

Default behavior of MediaActivity

  • activity is loaded without title (Android SDK reference: Window.FEATURE_NO_TITLE)
  • clicked links from provided media data are loaded inside this activity (not the web browser)
  • activity is able to load notification’s media data or URL provided in Intents extras
  • pressing back button goes back in the MediaWebView history
  • destroying activity removes all views and clears browsing history

Customizing activity behaviour

Showing progress while loading html

For the purpose of showing a progress above the title instead of showing an activity without a title, you will need to set an action MediaActivity.START_WITH_PROGRESS on the intent that starts MediaActivity. This progress looks different in some OS versions. In case you don’t want the progress to be displayed this way, you can add progress bar in HTML’s JavaScript, since MediaWebView supports its usage.

Note: If you applied theme @android:style/Theme.NoTitleBar to your application or this activity, progress won’t be shown.

Loading media data or url

MediaActivity is able to load media data or URL, like the MediaWebView. For displaying media data, put extra MediaActivity.EXTRA_DATA with media data as a value on intent that starts MediaActivity. In order to load an URL, put extra MediaActivity.EXTRA_URL with an URL as a value on Intent that starts this activity.

Usage

At first, you will need to include MediaActivity in application’s AndroidManifest.xml file with the hardwareAccelerated attribute set as true (read more about hardware acceleration here http://developer.android.com/guide/topics/graphics/hardware-accel.html):

<activity
    android:name="com.infobip.push.media.MediaActivity"
    android:hardwareAccelerated="true"
    android:screenOrientation="portrait">
</activity>

To test if it works, start the activity:

Intent intent = new Intent(context, MediaActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(MediaActivity.START_WITH_PROGRESS); // optional - extra for showing progress when the page is loading
intent.putExtra(MediaActivity.EXTRA_DATA, "<html><body> <h2>Testing media data</h2> <p>test</p> </body></html>");
context.startActivity(intent);

If you use default notification handling, start MediaActivity from AbstractPushReceiver.onNotificationOpened(PushNotification, Context) method like this:

@Override
protected void onNotificationOpened(PushNotification notification, Context context) {
    if (!TextUtils.isEmpty(notification.getMediaData())) {
        // setting up Intent for starting MediaActivity
        Intent intent = new Intent(context, MediaActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(MediaActivity.START_WITH_PROGRESS);
        intent.putExtra(MediaActivity.EXTRA_DATA, notification.getMediaData());
        // starting MediaActivity
        context.startActivity(intent);
    }
}

If you have overridden the default notification handling, set up MediaActivity starting Intent and put it on the PendingIntent.getActivity(Context, int, Intent, int) method that handles notification opened (clicked) event.

Error handling

Errors that occur in registerToChannels, getRegisteredChannels, notifyNotificationOpened and getUnreceivedNotifications, saveNewUserId methods could be checked with their appropriate listeners. Check other method’s errors with AbstractPushReceiver.onError(int, Context) method where integer value is the reason why the performed operation failed. For more information about an occurred error check you LogCat.

The table below lists possible errors received while using library methods. Performed operations include: register, unregister, registerToChannels, getRegisteredChannels, notifyNotificationOpened, getUnreceivedNotifications, saveNewUserId.

Reason Performed operation Description Value
OPERATION_FAILED register unregister registerToChannels getRegisteredChannels notifyNotificationOpened getUnreceivedNotifications saveNewUserId Performed operation failed 12
INTERNET_NOT_AVAILABLE register unregister registerToChannels getRegisteredChannels notifyNotificationOpened getUnreceivedNotifications saveNewUserId Internet access is unavailable 1
PUSH_SERVICE_NOT_AVAILABLE register unregister registerToChannels getRegisteredChannels notifyNotificationOpened getUnreceivedNotifications saveNewUserId Infobip Push service is currently unavailable 2
USER_NOT_REGISTERED unregister registerToChannels getRegisteredChannels notifyNotificationOpened getUnreceivedNotifications saveNewUserId User is not registered for receiving push notifications 4
GCM_ACCOUNT_MISSING register Google account is missing on the phone 8
GCM_AUTHENTICATION_FAILED register Authentication failed – your user’s Google account password is invalid 16
GCM_INVALID_SENDER register Invalid GCM sender ID 32
GCM_PHONE_REGISTRATION_ERROR register Phone registration error occurred 64
GCM_INVALID_PARAMETERS register Invalid parameters are sent 128
GCM_SERVICE_NOT_AVAILABLE register GCM service is unavailable 256
LIBRARY_NOT_INITIALIZED register unregister registerToChannels getRegisteredChannels notifyNotificationOpened getUnreceivedNotifications saveNewUserId Library is not initialized 512
USER_ALREADY_REGISTERED register User is already registered 1024

Debugging

Library’s debug mode is disabled by default. Enable it by setting boolean value to true in PushNotificationManager.setDebugModeEnabled(boolean) method, preferably right after you instantiate PushNotificationManager class. Once you enable the debug mode, you will see all the logging performed by the library in your LogCat. You can filter it by “Push library” tag.

If you are testing your application on an emulator, make sure that you’ve created an emulator targeting Google APIs.

Android GCM setup manual

Google Cloud Messaging

Google Cloud Messaging is a service which allows us to send data from the server to your users’ Android-powered device. To enable using push notifications within your app, you need to do the following:

Add your project (application) to Google Cloud Messaging.

Open the Google API Console. In case you never created a project you will see the following screen:

Create project
Create project

Click the Create project button. After filling in the Project name and Project ID, you will be shown a dashboard for your new project. Initially, that project will be named the “My Cloud Project”.

The most important thing you’ll need to acquire is the Project number which is displayed on the dashboard, along with the Project ID. Write down this number, because you will need it later to register your application. Project ID is not needed for enabling push notifications.

Project number
Project number

After finding out what your Project number is, you will have to enable Google Cloud Messaging for Android.

  • Find “APIs & auth” section in your projects’ menu and choose “APIs” section.
  • Find Google Cloud Messaging for Android on the list, and switch the button to ON.
Enabling Google Cloud Messaging
Enabling Google Cloud Messaging

Get your Google API Key. You will need this key in order to register your application on our Infobip Push platform. Go to “APIs & auth”, and choose “Credentials” from the menu. Under Public API access click “Create new key”, then choose “Server key”. In the resulting dialog, just click “Create” and your API key will be generated. Write this number down, you’ll need it later.

Registering app
Registering app
API key
API key
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s