Skip to content

Commit 183ec3d

Browse files
authored
Merge pull request #2 from Iterable/development
Development
2 parents 5b5721b + 50f4fac commit 183ec3d

File tree

6 files changed

+120
-79
lines changed

6 files changed

+120
-79
lines changed

iterableapi/src/main/java/com/iterable/iterableapi/IterableApi.java

+38-29
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,12 @@ public class IterableApi {
2424

2525
protected static IterableApi sharedInstance = null;
2626

27-
private Context _context;
27+
private Context _applicationContext;
2828
private String _apiKey;
2929
private String _email;
3030

3131
private Bundle _payloadData;
3232
private IterableNotificationData _notificationData;
33-
private String _pushToken;
3433

3534
private IterableApi(Context context, String apiKey, String email){
3635
updateData(context, apiKey, email);
@@ -39,40 +38,35 @@ private IterableApi(Context context, String apiKey, String email){
3938
/**
4039
* Returns a shared instance of IterableApi. Updates the client data if an instance already exists.
4140
* Should be called whenever the app is opened.
42-
* @param context The current activity
41+
* @param currentActivity The current activity
4342
* @return stored instance of IterableApi
4443
*/
45-
public static IterableApi sharedInstanceWithApiKey(Context context, String apiKey, String email)
44+
public static IterableApi sharedInstanceWithApiKey(Activity currentActivity, String apiKey, String email)
4645
{
46+
Context applicationContext = currentActivity.getApplicationContext();
47+
4748
if (sharedInstance == null)
4849
{
49-
sharedInstance = new IterableApi(context, apiKey, email);
50+
sharedInstance = new IterableApi(applicationContext, apiKey, email);
5051
} else{
51-
sharedInstance.updateData(context, apiKey, email);
52+
sharedInstance.updateData(applicationContext, apiKey, email);
5253
}
5354

54-
if (context instanceof Activity) {
55-
Activity currentActivity = (Activity) context;
56-
Intent calledIntent = currentActivity.getIntent();
57-
sharedInstance.tryTrackNotifOpen(calledIntent);
58-
}
59-
else {
60-
Log.d(TAG, "Notification Opens will not be tracked: "+
61-
"sharedInstanceWithApiKey called with a Context that is not an instance of Activity. " +
62-
"Pass in an Activity to IterableApi.sharedInstanceWithApiKey to enable open tracking.");
63-
}
55+
Intent calledIntent = currentActivity.getIntent();
56+
sharedInstance.setPayloadData(calledIntent);
57+
sharedInstance.tryTrackNotifOpen(calledIntent);
6458

6559
return sharedInstance;
6660
}
6761

6862
private void updateData(Context context, String apiKey, String email) {
69-
this._context = context;
63+
this._applicationContext = context;
7064
this._apiKey = apiKey;
7165
this._email = email;
7266
}
7367

7468
protected Context getMainActivityContext() {
75-
return _context;
69+
return _applicationContext;
7670
}
7771

7872
/**
@@ -81,13 +75,11 @@ protected Context getMainActivityContext() {
8175
* @param iconName
8276
*/
8377
public void setNotificationIcon(String iconName) {
84-
setNotificationIcon(_context, iconName);
78+
setNotificationIcon(_applicationContext, iconName);
8579
}
8680

87-
protected void setPushToken(String token) { _pushToken = token; }
88-
8981
protected static void setNotificationIcon(Context context, String iconName) {
90-
SharedPreferences sharedPref = ((Activity) context).getSharedPreferences(NOTIFICATION_ICON_NAME, Context.MODE_PRIVATE);
82+
SharedPreferences sharedPref = context.getSharedPreferences(NOTIFICATION_ICON_NAME, Context.MODE_PRIVATE);
9183
SharedPreferences.Editor editor = sharedPref.edit();
9284
editor.putString(NOTIFICATION_ICON_NAME, iconName);
9385
editor.commit();
@@ -107,21 +99,26 @@ protected static String getNotificationIcon(Context context) {
10799
* - https://console.developers.google.com/iam-admin/settings
108100
*/
109101
public void registerForPush(String iterableAppId, String gcmProjectId) {
110-
Intent pushRegistrationIntent = new Intent(_context, IterablePushReceiver.class);
102+
registerForPush(iterableAppId, gcmProjectId, false);
103+
}
104+
105+
protected void registerForPush(String iterableAppId, String gcmProjectId, boolean disableAfterRegistration) {
106+
Intent pushRegistrationIntent = new Intent(_applicationContext, IterablePushReceiver.class);
111107
pushRegistrationIntent.setAction(IterableConstants.ACTION_PUSH_REGISTRATION);
112108
pushRegistrationIntent.putExtra(IterableConstants.PUSH_APPID, iterableAppId);
113109
pushRegistrationIntent.putExtra(IterableConstants.PUSH_PROJECTID, gcmProjectId);
114-
_context.sendBroadcast(pushRegistrationIntent);
110+
pushRegistrationIntent.putExtra(IterableConstants.PUSH_DISABLE_AFTER_REGISTRATION, disableAfterRegistration);
111+
_applicationContext.sendBroadcast(pushRegistrationIntent);
115112
}
116113

117114
private void tryTrackNotifOpen(Intent calledIntent) {
118115
Bundle extras = calledIntent.getExtras();
119116
if (extras != null) {
120117
Intent intent = new Intent();
121-
intent.setClass(_context, IterablePushOpenReceiver.class);
118+
intent.setClass(_applicationContext, IterablePushOpenReceiver.class);
122119
intent.setAction(IterableConstants.ACTION_NOTIF_OPENED);
123120
intent.putExtras(extras);
124-
_context.sendBroadcast(intent);
121+
_applicationContext.sendBroadcast(intent);
125122
}
126123
}
127124

@@ -314,18 +311,23 @@ public void updateUser(JSONObject dataFields) {
314311
}
315312

316313
public void disablePush(String iterableAppId, String gcmProjectId) {
317-
registerForPush(iterableAppId, gcmProjectId);
314+
registerForPush(iterableAppId, gcmProjectId, true);
315+
}
318316

317+
/**
318+
* Internal api call made from IterablePushRegistrionGCM after a registration is completed.
319+
* @param token
320+
*/
321+
protected void disablePush(String token) {
319322
JSONObject requestJSON = new JSONObject();
320323
try {
321-
requestJSON.put(IterableConstants.KEY_TOKEN, _pushToken);
324+
requestJSON.put(IterableConstants.KEY_TOKEN, token);
322325
requestJSON.put(IterableConstants.KEY_EMAIL, _email);
323326
}
324327
catch (JSONException e) {
325328
e.printStackTrace();
326329
}
327330
sendRequest(IterableConstants.ENDPOINT_DISABLEDEVICE, requestJSON);
328-
329331
}
330332

331333
/**
@@ -342,6 +344,13 @@ public String getPayloadData(String key) {
342344
return dataString;
343345
}
344346

347+
void setPayloadData(Intent intent) {
348+
Bundle extras = intent.getExtras();
349+
if (extras != null && !extras.isEmpty() && extras.containsKey(IterableConstants.ITERABLE_DATA_KEY)) {
350+
setPayloadData(extras);
351+
}
352+
}
353+
345354
void setPayloadData(Bundle bundle) {
346355
_payloadData = bundle;
347356
}

iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public final class IterableConstants {
4141

4242
public static final String PUSH_APPID = "IterableAppId";
4343
public static final String PUSH_PROJECTID = "GCMProjectNumber";
44+
public static final String PUSH_DISABLE_AFTER_REGISTRATION = "DisableAfterRegistration";
4445

4546
public static final String MESSAGING_PLATFORM_GOOGLE = "GCM";
4647
public static final String MESSAGING_PLATFORM_AMAZON = "ADM";

iterableapi/src/main/java/com/iterable/iterableapi/IterablePushOpenReceiver.java

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ public void onReceive(Context context, Intent intent) {
3131
String iterableDataString = extras.getString(IterableConstants.ITERABLE_DATA_KEY);
3232
IterableNotificationData iterableNotificationData = new IterableNotificationData(iterableDataString);
3333
if (IterableApi.sharedInstance != null) {
34-
IterableApi.sharedInstance.setPayloadData(extras);
3534
IterableApi.sharedInstance.setNotificationData(iterableNotificationData);
3635
IterableApi.sharedInstance.trackPushOpen(iterableNotificationData.getCampaignId(), iterableNotificationData.getTemplateId());
3736
}

iterableapi/src/main/java/com/iterable/iterableapi/IterablePushReceiver.java

+29-27
Original file line numberDiff line numberDiff line change
@@ -34,41 +34,43 @@ public void onReceive(Context context, Intent intent) {
3434
private void handlePushRegistration(Context context, Intent intent) {
3535
String iterableAppId = intent.getStringExtra(IterableConstants.PUSH_APPID);
3636
String projectNumber = intent.getStringExtra(IterableConstants.PUSH_PROJECTID);
37-
IterableGCMRegistrationData data = new IterableGCMRegistrationData(iterableAppId, projectNumber);
37+
boolean disablePush = intent.getBooleanExtra(IterableConstants.PUSH_DISABLE_AFTER_REGISTRATION, false);
38+
IterableGCMRegistrationData data = new IterableGCMRegistrationData(iterableAppId, projectNumber, disablePush);
3839
new IterablePushRegistrationGCM().execute(data);
3940
}
4041

4142
private void handlePushReceived(Context context, Intent intent) {
42-
Context appContext = context.getApplicationContext();
43-
44-
PackageManager packageManager = appContext.getPackageManager();
45-
Intent packageIntent = packageManager.getLaunchIntentForPackage(appContext.getPackageName());
46-
ComponentName componentPackageName = packageIntent.getComponent();
47-
String mainClassName = componentPackageName.getClassName();
48-
Class mainClass = null;
49-
try {
50-
mainClass = Class.forName(mainClassName);
51-
} catch (ClassNotFoundException e) {
52-
e.printStackTrace();
53-
}
43+
if (intent.hasExtra(IterableConstants.ITERABLE_DATA_KEY)) {
44+
Context appContext = context.getApplicationContext();
45+
PackageManager packageManager = appContext.getPackageManager();
46+
Intent packageIntent = packageManager.getLaunchIntentForPackage(appContext.getPackageName());
47+
ComponentName componentPackageName = packageIntent.getComponent();
48+
String mainClassName = componentPackageName.getClassName();
49+
Class mainClass = null;
50+
try {
51+
mainClass = Class.forName(mainClassName);
52+
} catch (ClassNotFoundException e) {
53+
e.printStackTrace();
54+
}
5455

55-
int iconId = appContext.getResources().getIdentifier(
56-
IterableApi.getNotificationIcon(context),
57-
"drawable",
58-
appContext.getPackageName());
56+
int iconId = appContext.getResources().getIdentifier(
57+
IterableApi.getNotificationIcon(context),
58+
"drawable",
59+
appContext.getPackageName());
5960

60-
if (iconId == 0) {
61-
iconId = appContext.getApplicationInfo().icon;
62-
if (iconId != 0){
63-
Log.d(TAG, "No Notification Icon defined - defaulting to app icon");
64-
} else {
65-
Log.w(TAG, "No Notification Icon defined - push notifications will not be displayed");
61+
if (iconId == 0) {
62+
iconId = appContext.getApplicationInfo().icon;
63+
if (iconId != 0) {
64+
Log.d(TAG, "No Notification Icon defined - defaulting to app icon");
65+
} else {
66+
Log.w(TAG, "No Notification Icon defined - push notifications will not be displayed");
67+
}
6668
}
67-
}
6869

69-
IterableNotification notificationBuilder = IterableNotification.createNotification(
70-
appContext, intent.getExtras(), mainClass, iconId);
70+
IterableNotification notificationBuilder = IterableNotification.createNotification(
71+
appContext, intent.getExtras(), mainClass, iconId);
7172

72-
IterableNotification.postNotificationOnDevice(appContext, notificationBuilder);
73+
IterableNotification.postNotificationOnDevice(appContext, notificationBuilder);
74+
}
7375
}
7476
}

iterableapi/src/main/java/com/iterable/iterableapi/IterablePushRegistrationGCM.java

+23-5
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,24 @@
1414
class IterablePushRegistrationGCM extends AsyncTask<IterableGCMRegistrationData, Void, String> {
1515
static final String TAG = "IterableGCM";
1616

17+
private IterableGCMRegistrationData iterableGCMRegistrationData;
18+
private boolean disableAfterRegistration;
19+
1720
protected String doInBackground(IterableGCMRegistrationData... params) {
21+
String registrationToken = "";
22+
1823
try {
19-
IterableGCMRegistrationData iterableGCMRegistrationData = params[0];
24+
iterableGCMRegistrationData = params[0];
2025

2126
if (iterableGCMRegistrationData.iterableAppId != null) {
2227
Class instanceIdClass = Class.forName("com.google.android.gms.iid.InstanceID");
2328
if (instanceIdClass != null) {
2429
InstanceID instanceID = InstanceID.getInstance(IterableApi.sharedInstance.getMainActivityContext());
25-
String registrationToken = "";
30+
2631
String idInstance = instanceID.getId();
2732
registrationToken = instanceID.getToken(iterableGCMRegistrationData.projectNumber,
2833
GoogleCloudMessaging.INSTANCE_ID_SCOPE);
2934
if (!registrationToken.isEmpty()) {
30-
IterableApi.sharedInstance.setPushToken(registrationToken);
3135
IterableApi.sharedInstance.registerDeviceToken(iterableGCMRegistrationData.iterableAppId, registrationToken);
3236
}
3337
}
@@ -44,16 +48,30 @@ protected String doInBackground(IterableGCMRegistrationData... params) {
4448
e.printStackTrace();
4549
Log.e(TAG, "Invalid projectNumber");
4650
}
47-
return null;
51+
return registrationToken;
52+
}
53+
54+
@Override
55+
protected void onPostExecute(String registrationToken) {
56+
super.onPostExecute(registrationToken);
57+
if (iterableGCMRegistrationData.disableAfterRegistration) {
58+
disableOnRegistrationComplete(registrationToken);
59+
}
60+
}
61+
62+
protected void disableOnRegistrationComplete(String registrationToken) {
63+
IterableApi.sharedInstance.disablePush(registrationToken);
4864
}
4965
}
5066

5167
class IterableGCMRegistrationData {
5268
String iterableAppId = "";
5369
String projectNumber = "";
54-
public IterableGCMRegistrationData(String iterableAppId, String projectNumber){
70+
boolean disableAfterRegistration = false;
71+
public IterableGCMRegistrationData(String iterableAppId, String projectNumber, boolean disableAfterRegistration){
5572
this.iterableAppId = iterableAppId;
5673
this.projectNumber = projectNumber;
74+
this.disableAfterRegistration = disableAfterRegistration;
5775
}
5876
}
5977

iterableapi/src/main/java/com/iterable/iterableapi/IterableRequest.java

+29-17
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,36 @@
1919
class IterableRequest extends AsyncTask<IterableApiRequest, Void, String> {
2020
static final String TAG = "IterableRequest";
2121
static final String AUTHENTICATION_IO_EXCEPTION = "Received authentication challenge is null";
22-
static final int DEFAULT_TIMEOUT = 10000;
23-
24-
long retryDelay = 10000;
2522

2623
static final String iterableBaseUrl = "https://api.iterable.com/api/";
27-
2824
static String overrideUrl;
2925

26+
static final int DEFAULT_TIMEOUT = 10000;
27+
static final long RETRY_DELAY = 10000;
28+
static final int MAX_RETRY_COUNT = 3;
29+
30+
int retryCount = 0;
31+
IterableApiRequest iterableApiRequest;
32+
boolean retryRequest;
33+
3034
/**
3135
* Sends the given request to Iterable using a HttpUserConnection
3236
* Reference - http://developer.android.com/reference/java/net/HttpURLConnection.html
3337
* @param params
3438
* @return
3539
*/
3640
protected String doInBackground(IterableApiRequest... params) {
37-
IterableApiRequest iterableApiRequest = params[0];
41+
if (params != null && params.length > 0) {
42+
iterableApiRequest = params[0];
43+
}
44+
45+
if (retryRequest) {
46+
try {
47+
Thread.sleep(RETRY_DELAY * retryCount);
48+
} catch (InterruptedException e) {
49+
e.printStackTrace();
50+
}
51+
}
3852

3953
String requestResult = null;
4054
if (iterableApiRequest != null) {
@@ -77,14 +91,13 @@ protected String doInBackground(IterableApiRequest... params) {
7791
String mess = e.getMessage();
7892
if (mess.equals(AUTHENTICATION_IO_EXCEPTION)) {
7993
Log.d(TAG, "Invalid API Key");
80-
} else
81-
{
82-
retryRequest(iterableApiRequest);
94+
} else {
95+
retryRequest = true;
8396
}
8497
e.printStackTrace();
8598
} catch (Exception e) {
8699
e.printStackTrace();
87-
retryRequest(iterableApiRequest);
100+
retryRequest = true;
88101
} finally {
89102
if (urlConnection != null) {
90103
urlConnection.disconnect();
@@ -96,17 +109,16 @@ protected String doInBackground(IterableApiRequest... params) {
96109

97110
@Override
98111
protected void onPostExecute(String s) {
112+
if (retryRequest && retryCount <= MAX_RETRY_COUNT) {
113+
IterableRequest request = new IterableRequest();
114+
request.setRetryCount(retryCount + 1);
115+
request.execute(iterableApiRequest);
116+
}
99117
super.onPostExecute(s);
100118
}
101119

102-
private void retryRequest(IterableApiRequest iterableApiRequest) {
103-
try {
104-
wait(retryDelay);
105-
} catch (InterruptedException e) {
106-
e.printStackTrace();
107-
}
108-
retryDelay *= 2; //exponential retry backoff
109-
doInBackground(iterableApiRequest);
120+
protected void setRetryCount(int count) {
121+
retryCount = count;
110122
}
111123

112124
}

0 commit comments

Comments
 (0)