Customizing Android SDK

In App Purchase tracking

In order to track in-app purchases you should call the trackInAppRequest method of the PushManager class when a user buys a product:

public static void trackInAppRequest(Context context, String sku, BigDecimal price, String currency, Date purchaseTime)
  • sku – purchased product ID
  • price – price of the product
  • currency – currency of the price (ex: “USD”)
  • purchaseTime – time of the purchase (ex: new Date())

Example:

pushManager.trackInAppRequest(context, "com.example.inapp1", "1.99", "USD", new Date());

Deep linking

In your activity that will handle the deep link add <data> tag with the scheme, host and pathPrefix parameters.

<activity
          android:name=".PromoActivity"
          android:label="PromoActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data android:scheme="com.pushwoosh"
          android:host="promotion"
          android:pathPrefix="" />
    </intent-filter>
</activity>

Note that deep link page name (promotion in the example) goes to the host field, not pathPrefix.

In the example above the deep link will open PromoActivity. The basic implementation below displays alert with promo id value for the sake of simplicity. In your application it could definitely do something useful!

public class PromoActivity extends Activity
{
		@Override
		protected void onCreate(Bundle savedInstanceState)
		{
				super.onCreate(savedInstanceState);

				setContentView(R.layout.deep_link);
				setTitle("Deep link activity");
		
				Intent intent = getIntent();
	  	  String action = intent.getAction();
	    	Uri data = intent.getData();
	    
		    if (TextUtils.equals(action, Intent.ACTION_VIEW))
		    {
	  		  	openUrl(data);
		    }
		}
	
		private void openUrl(Uri uri) 
		{
				String promoId = uri.getQueryParameter("id");
				Toast.makeText(getApplicationContext(), promoId, Toast.LENGTH_LONG).show();
		}
}

Geozones push notifications

Add the following changes to AndroidManifest.xml.
You should also call startTrackingGeoPushes() method of PushManager object. Please see (Pushwoosh Android SDK API).

<!-- Geo location permissions: -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Using Beacons

1. Add Bluetooth permissions to your manifest file as follows:

<!-- Bluetooth permissions: -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

2. Use the following methods of the PushManager in order to enable and disable scanning for available iBeacons in the area:

  • public void startTrackingBeaconPushes();
  • public void stopTrackingBeaconPushes();

Please see (Pushwoosh Android SDK API).

3. The public static void setBeaconBackgroundMode(Context context, boolean backgroundMode) method notifies the iBeacon service that the IBeaconConsumer is either moving to background mode or foreground mode. When in background mode, BluetoothLE scans to look for iBeacons are executed less frequently in order to save battery life.

Using Local Notifications with Pushwoosh

If you use Pushwoosh Local Notifications API add RECEIVE_BOOT_COMPLETED permission to your AndroidManifest.xml:

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

Using Badge Number on Android

Pushwoosh supports setting badge number on the app icon shortcut for the following Android launchers:
Sony, Samsung, LG, HTC, Xiaomi, ASUS, ADW, APEX, NOVA, HUAWEI, ZUK, OPPO

You need to add following permissions to your AndroidManifest.xml

<!-- for Samsung -->
<uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>

<!--for htc-->
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT"/>

<!--for sony-->
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/>
<uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE"/>

<!--for apex-->
<uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/>

<!--for solid-->
<uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE"/>

<!--for huawei-->
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE"/>
<uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS"/>

<!--for ZUK-->
<uses-permission android:name="android.permission.READ_APP_BADGE"/>

<!--for OPPO-->
<uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS"/>

Opening custom activity

If you want to start particular activity in response to push notifications add the following intent-filter to that activity.

<activity android:name="YourActivity">
    <intent-filter>
        <action android:name="${applicationId}.MESSAGE"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

Controlling Log Level

In order to assist with debugging and integration, SDK will print all the requests to the console by default. When you ready for the production build, add "PW_LOG_LEVEL" meta-data with value "ERROR" to the AndroidManifest.xml. This way only information about errors will go to the console. Other option could be one of the following:

NONE - No logs from the SDK
ERROR - Display only errors in the console
WARN - Display also a warnings
INFO - Display informational messages
DEBUG - Even debug information is displayed now
NOISE - Everything SDK can print and more

<meta-data android:name="PW_LOG_LEVEL" android:value="ERROR" />

Using Proguard

When using Proguard add the following options:

-keep class com.pushwoosh.** { *; }
-keep class com.arellomobile.** { *; }
-dontwarn com.pushwoosh.**
-dontwarn com.arellomobile.**

Also see Google Play Services library requirements regarding Proguard here:
https://developers.google.com/android/guides/setup

Using Custom Push Broadcast Receiver in Android

If you need to programmatically select which activity to display as a result of push notification, you can create custom broadcast receiver to receive push notification tap event. You also have to add your receiver to AndroidManifest.xml. Then include fully qualified class name of the receiver in metadata under “PW_NOTIFICATION_RECEIVER” value.

<receiver android:name="your.app.package.NotificationReceiver" />
<meta-data android:name="PW_NOTIFICATION_RECEIVER" android:value="${notificationReceiverPackage}.NotificationReceiver"/>

Example of the receiver (note pre- and post-handling functions):

public class NotificationReceiver extends BroadcastReceiver
{
    public void onReceive(Context context, Intent intent)
    {
        if (intent == null)
            return;
 
        //Let Pushwoosh SDK to pre-handling push (Pushwoosh track stats, opens rich pages, etc.).
        //It will return Bundle with a push notification data
        Bundle pushBundle = PushManagerImpl.preHandlePush(context, intent);
        if(pushBundle == null)
            return;
             
        //get push bundle as JSON object
        JSONObject dataObject = PushManagerImpl.bundleToJSON(pushBundle);
         
        //Get default launcher intent for clarity
        Intent launchIntent  = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
        launchIntent.addCategory("android.intent.category.LAUNCHER");
             
        launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
 
        //Put push notifications payload in Intent
        launchIntent.putExtras(pushBundle);
        launchIntent.putExtra(PushManager.PUSH_RECEIVE_EVENT, dataObject.toString());
 
        //Start activity!
        context.startActivity(launchIntent);
         
        //Let Pushwoosh SDK post-handle push (track stats, etc.)
        PushManagerImpl.postHandlePush(context, intent);
    }
}

Customizing push notifications

To customize the view of push notification alerts you need to create a custom Factory.
Inherit from AbsNotificationFactory class and override the following methods:

	/**
	 * Generates notification using pushData
	 * @param pushData push params
	 * @return Notification to show
	 */
	public abstract Notification onGenerateNotification(PushData pushData);

	/**
	 * Callback for notification delivery event
	 *
	 * @param pushData push params
	 */
	public abstract void onPushReceived(PushData pushData);

	/**
	 * Callback after notification click
	 * @param activity context
	 */
	public abstract void onPushHandle(Activity activity);

Everything is better with an example!

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;

import com.pushwoosh.notification.AbsNotificationFactory;
import com.pushwoosh.notification.PushData;

import android.net.Uri;
import android.support.v4.app.NotificationCompat;

/**
 * Notification factory sample for remote notification actions
 * Android root params example : { "my_actions" : [ { "title" : "Pushwoosh", "url" : "https://www.pushwoosh.com"  } ] }
 */
public class NotificationFactorySample extends AbsNotificationFactory
{
	@Override
	public Notification onGenerateNotification(PushData pushData)
	{
		//create notification builder
		NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getContext());
		
		//set title of notification
		 notificationBuilder.setContentTitle(getContentFromHtml(pushData.getHeader()));
		
		//set content of notification
		  notificationBuilder.setContentText(getContentFromHtml(pushData.getMessage()));
		
		//set small icon (usually app icon)
		notificationBuilder.setSmallIcon(pushData.getSmallIcon());
		
		//set ticket text
		notificationBuilder.setTicker(getContentFromHtml(pushData.getTicker()));
		
		//display notification now
		notificationBuilder.setWhen(System.currentTimeMillis());
		
		//add actions to the notification
		addRemoteActions(notificationBuilder, pushData);
		
		if (pushData.getBigPicture() != null)
		{
		    //set big image if available
			notificationBuilder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(pushData.getBigPicture()).setSummaryText(getContentFromHtml(pushData.getMessage())));
		}
		else
		{
		    //otherwise it's big text style
		    notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(getContentFromHtml(pushData.getMessage())));
		}
		
		//support icon background color
		if (pushData.getIconBackgroundColor() != null)
		{
		      notificationBuilder.setColor(pushData.getIconBackgroundColor());
		}
		
		//support custom icon
		if (null != pushData.getLargeIcon())
		{
		    notificationBuilder.setLargeIcon(pushData.getLargeIcon());
		}
		
		//build the notification
		final Notification notification = notificationBuilder.build();
		
		//add sound
		addSound(notification, pushData.getSound());
		
		//add vibration
		addVibration(notification, pushData.getVibration());
		
		//make it cancelable
		addCancel(notification);
		
		//all done!
		return notification;
	}
	
	private void addRemoteActions(NotificationCompat.Builder notificationBuilder, PushData pushData)
	{
		String actions = pushData.getExtras().getString("my_actions");
		if (actions != null)
		{
			try
			{
				JSONArray jsonArray = new JSONArray(actions);
				for (int i = 0; i < jsonArray.length(); ++i)
				{
					JSONObject json = jsonArray.getJSONObject(i);
					String title = json.getString("title");
					String url = json.getString("url");
					Intent actionIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
					notificationBuilder.addAction(new NotificationCompat.Action(0, title, PendingIntent.getActivity(getContext(), 0, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT)));
				}
			}
			catch (JSONException e)
			{
				e.printStackTrace();
			}
		}
	}

	@Override
	public void onPushReceived(PushData pushData)
	{
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onPushHandle(Activity activity)
	{
		// TODO Auto-generated method stub
		
	}
}

The last step is to set your notification Factory to the Push Manager:

pushManager.setNotificationFactory(new NotificationFactorySample());

Private Endpoint URL

Enterprise only.

Pushwoosh provides Private endpoints for Enterprise customers. To set up Private endpoint for iOS SDK you need to add the following to your AndroidManifest.xml file

<meta-data android:name="PushwooshUrl" android:value="PUSHWOOSH_PRIVATE_ENDPOINT_URL_PROVIDED" />

Customizing Android SDK