Skip to content

Commit

Permalink
Version 1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
jtreanor committed Jun 5, 2015
1 parent 0a2aa5a commit b495b4b
Show file tree
Hide file tree
Showing 12 changed files with 222 additions and 12 deletions.
8 changes: 8 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
= 1.0.1 (2015-06-05)

* Improved push notification handling by introducing much simpler `intercom.registerForPush(senderId)`.
* Updated Intercom for iOS to 2.2.4 and updated Intercom for Android to 1.0.3.

= 1.0.0 (2015-05-25)

* Initial release of the Intercom plugin for Cordova and PhoneGap.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,21 @@ Events can optionally include meta data:

Intercom for mobile supports Push Notifications on iOS and Google Cloud Messaging (GCM). To get started, you can read our GCM docs [here](http://docs.intercom.io/Install-on-your-mobile-product/using-google-cloud-messaging-gcm-with-intercom-for-android) and our iOS push notification docs [here](http://docs.intercom.io/Install-on-your-mobile-product/enabling-push-notifications-with-intercom-for-ios).

On iOS, you should call `intercom.setupAPN(deviceToken);` instead of `[Intercom setDeviceToken:deviceToken];`.
To enable iOS push notifications, simply call `intercom.registerForPush()`.

For Android, call `intercom.setupGCM(registrationId);` instead of `Intercom.getClient().setupGCM(regId, icon);` and call `intercom.openGCMMessage();` instead of `Intercom.getClient().openGCMMessage(...);`.
To enable Android push notifications, call `intercom.registerForPush('sender_id')` and add these permissions just before the existing `<application>` element in your `platforms/android/AndroidManifest.xml` file:

**Note:** _Unlike the native Android interface, `Intercom.getClient().openGCMMessage(...);` has no return value indicating if the message was handled by Intercom. It is up to you to decide to pass the message or not._
```
<!-- GCM REQUIRED PERMISSIONS -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.VIBRATE" />
<!-- GCM Optional PERMISSIONS -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
```

**Note:** _If you use PushPlugin to support non Intercom push notifications in addition to Intercom's notifications, you must use our fork which is available [here](https://github.com/intercom/PushPlugin). We know this is not ideal but unfortunately it is necessary due to the inflexible nature of PushPlugin_

## More information

Expand Down
5 changes: 3 additions & 2 deletions plugin.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<plugin id="io.intercom.cordova" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<plugin id="io.intercom.cordova" version="1.0.1" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>Intercom</name>
<author>Intercom</author>
<license>MIT License</license>
Expand Down Expand Up @@ -61,7 +61,8 @@
<preference name="ANDROID_API_KEY"/>

<source-file src="src/android/IntercomBridge.java" target-dir="src/io/intercom/android/sdk" />
<source-file src="src/android/libs/intercom-sdk-1.0.1.aar" target-dir="libs" />
<source-file src="src/android/IntercomGCMManager.java" target-dir="src/io/intercom/android/sdk" />
<source-file src="src/android/libs/intercom-sdk-1.0.3.aar" target-dir="libs" />
<framework src="src/android/intercom.gradle" custom="true" type="gradleReference" />

<config-file target="config.xml" parent="*/">
Expand Down
24 changes: 24 additions & 0 deletions src/android/IntercomBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
import android.content.Intent;

import android.content.Context;
import android.content.pm.ApplicationInfo;
Expand All @@ -16,6 +17,7 @@

import io.intercom.android.sdk.identity.Registration;
import io.intercom.android.sdk.preview.IntercomPreviewPosition;
import io.intercom.android.sdk.api.HeaderInterceptor;

import java.util.Map;
import java.util.HashMap;
Expand All @@ -32,13 +34,24 @@ public class IntercomBridge extends CordovaPlugin {
@Override public void onStart() {
//We also initialize intercom here just in case it has died. If Intercom is already set up, this won't do anything.
this.setUpIntercom();

if (Intercom.client().openGCMMessage(cordova.getActivity().getIntent().getData())) {
cordova.getActivity().getIntent().setData(null);
}
}

@Override public void onNewIntent(Intent intent) {
cordova.getActivity().setIntent(intent);
}

private void setUpIntercom() {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override public void run() {
try {
Context context = IntercomBridge.this.cordova.getActivity().getApplicationContext();

HeaderInterceptor.setCordovaVersion(context, "1.0.1");

ApplicationInfo app = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
Bundle bundle = app.metaData;

Expand Down Expand Up @@ -158,6 +171,17 @@ private enum Action {
callbackContext.success();
}
},
registerForPush {
@Override void performAction(JSONArray args, CallbackContext callbackContext, CordovaInterface cordova) {
String senderId = args.optString(0);
if (senderId == null) {
callbackContext.error("[Intercom-Cordova] ERROR: Tried to setup GCM with no sender Id.");
} else {
IntercomGCMManager.setUpPush(senderId, cordova.getActivity().getApplicationContext());
callbackContext.success();
}
}
},
setupAPN {
@Override void performAction(JSONArray args, CallbackContext callbackContext, CordovaInterface cordova) {
callbackContext.error("[Intercom-Cordova] ERROR: Tried to setup iOS push notifications on Android. Use setupGCM instead.");
Expand Down
136 changes: 136 additions & 0 deletions src/android/IntercomGCMManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package io.intercom.android.sdk;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;

import java.io.IOException;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageInfo;

import android.annotation.SuppressLint;

import android.os.Build;
import android.os.AsyncTask;
import android.os.Handler;

import android.util.Log;


public class IntercomGCMManager {
private static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "app_version";

private static long retryTime = 0;
private static int retryCount = 0;

private static GoogleCloudMessaging gcm;
public static String regId;

private static Handler gcmHandler = new Handler();

public static void setUpPush(String senderId, Context context) {
if (checkPlayServices(context)) {
gcm = GoogleCloudMessaging.getInstance(context);
regId = getRegistrationId(context);

if (regId.isEmpty()) {
registerInBackground(senderId, context);
} else {
sendRegistrationIdToBackend(regId, context);
}
} else {
Log.i("GCM_ISSUE", "No valid Google Play Services APK found.");
}
}

public static boolean checkPlayServices(Context context) {
return GooglePlayServicesUtil.isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS;
}

private static String getRegistrationId(Context context) {
SharedPreferences prefs = context.getSharedPreferences("gcmDetails", Context.MODE_PRIVATE);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.isEmpty()) {
Log.d("GCM_ISSUE", "Registration ID not found.");
return "";
}
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) {
Log.d("GCM_ISSUE", "App version changed.");
return "";
}
return registrationId;
}

private static int getAppVersion(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("Could not get package name: " + e);
}
}

@SuppressLint("CommitPrefEdits") private static void storeRegistrationId(Context context, String regId) {
SharedPreferences prefs = context.getSharedPreferences("gcmDetails", Context.MODE_PRIVATE);
int appVersion = getAppVersion(context);

Log.i("GCM_SUCCESS", "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regId);
editor.putInt(PROPERTY_APP_VERSION, appVersion);
editor.commit();
}

private static void registerInBackground(final String senderId, final Context context) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regId = gcm.register(senderId);

sendRegistrationIdToBackend(regId, context);
storeRegistrationId(context, regId);

Log.d("GCM_SUCCESS", "Current Device's Registration ID is: " + msg);
} catch (IOException ex) {
Log.d("GCM_ISSUE", "Error :" + ex.getMessage());

retryCount++;

long minBackoffSeconds = (long)Math.pow(2.0, (double)retryCount);
long backOffJitter = (long)(Math.random() * (minBackoffSeconds + 1));
retryTime = minBackoffSeconds + backOffJitter;

//retry the registration after delay
gcmHandler.postDelayed(new Runnable() {
@Override
public void run() {
registerInBackground(senderId, context);
}
}, retryTime);
}
return null;
}
}.execute(null, null, null);
}

private static void sendRegistrationIdToBackend(String regId, Context context) {
int resourceId = -1; //Don't use the app icon in lollipop as it doesn't work nicely
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
resourceId = context.getApplicationInfo().icon;
}
Intercom.client().setupGCM(regId, resourceId);
}
}
9 changes: 4 additions & 5 deletions src/android/intercom.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ repositories {
}
}
dependencies {
compile ('io.intercom.android:intercom-sdk:1.0.1@aar')
compile 'com.android.support:support-v4:22.1.1'
compile ('io.intercom.android:intercom-sdk:1.0.3@aar')
compile 'com.google.code.gson:gson:2.3.1'
compile 'com.squareup:otto:1.3.7'
compile 'com.squareup.okhttp:okhttp:2.3.0'
compile 'com.squareup.okhttp:okhttp-ws:2.3.0'
compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.squareup.okhttp:okhttp-ws:2.4.0'
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.google.android.gms:play-services-gcm:7.3.0'
compile 'com.google.android.gms:play-services-gcm:7.5.0'
}
Binary file not shown.
2 changes: 1 addition & 1 deletion src/ios/Intercom.framework/Versions/A/Headers/Intercom.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#import <UIKit/UIKit.h>

#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
#error This version (2.2.3) of Intercom for iOS supports iOS 7.0 upwards.
#error This version (2.2.4) of Intercom for iOS supports iOS 7.0 upwards.
#endif

// Use these values to constrain an incoming notification view to a defined section of the window.
Expand Down
Binary file modified src/ios/Intercom.framework/Versions/A/Intercom
Binary file not shown.
2 changes: 2 additions & 0 deletions src/ios/IntercomBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@
- (void)setupGCM:(CDVInvokedUrlCommand*)command;
- (void)openGCMMessage:(CDVInvokedUrlCommand*)command;

- (void)registerForPush:(CDVInvokedUrlCommand*)command;

@end
28 changes: 27 additions & 1 deletion src/ios/IntercomBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ + (void)setCordovaVersion:(NSString *)v;
@implementation IntercomBridge : CDVPlugin

- (void)pluginInitialize {
[Intercom setCordovaVersion:@"1.0.0"];
[Intercom setCordovaVersion:@"1.0.1"];
#ifdef DEBUG
[Intercom enableLogging];
#endif
Expand Down Expand Up @@ -117,6 +117,32 @@ - (void)setupAPN:(CDVInvokedUrlCommand*)command {
[self sendSuccess:command];
}

- (void)registerForPush:(CDVInvokedUrlCommand*)command {
UIApplication *application = [UIApplication sharedApplication];
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]){ // iOS 8 (User notifications)
[application registerUserNotificationSettings:
[UIUserNotificationSettings settingsForTypes:
(UIUserNotificationTypeBadge |
UIUserNotificationTypeSound |
UIUserNotificationTypeAlert)
categories:nil]];
[application registerForRemoteNotifications];
} else { // iOS 7 (Remote notifications)
[application registerForRemoteNotificationTypes:
(UIRemoteNotificationType)
(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert)];
}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
[Intercom registerForRemoteNotifications];
#pragma GCC diagnostic pop

[self sendSuccess:command];
}

//These are the Android push methods. Only here to log errors.
- (void)setupGCM:(CDVInvokedUrlCommand*)command {
NSLog(@"[Intercom-Cordova] ERROR - Tried to setup GCM on iOS. Use setupGCM instead");
Expand Down
4 changes: 4 additions & 0 deletions www/intercom.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ var intercom = {
//iOS only: Push notification handling
setupAPN: function(deviceToken, success, error) {
cordova.exec(success, error, 'Intercom', 'setupAPN', []);
},

registerForPush: function(senderId, success, error) {
cordova.exec(success, error, 'Intercom', 'registerForPush', [senderId]);
}
}

Expand Down

0 comments on commit b495b4b

Please sign in to comment.