3030import java .io .PrintWriter ;
3131import java .io .StringWriter ;
3232import java .io .UnsupportedEncodingException ;
33+ import java .lang .annotation .ElementType ;
34+ import java .lang .annotation .Retention ;
35+ import java .lang .annotation .RetentionPolicy ;
36+ import java .lang .annotation .Target ;
3337import java .lang .reflect .Field ;
3438import java .util .ArrayList ;
3539import java .util .Calendar ;
5963import android .net .Uri ;
6064import android .os .Build ;
6165import android .os .Bundle ;
66+ import android .os .Looper ;
6267import android .os .SystemClock ;
6368import android .util .Log ;
6469import android .util .TypedValue ;
@@ -72,6 +77,10 @@ public enum LOG_LEVEL {
7277 NONE , FATAL , ERROR , WARN , INFO , DEBUG , VERBOSE
7378 }
7479
80+ @ Retention (RetentionPolicy .RUNTIME )
81+ @ Target (ElementType .TYPE )
82+ public @interface TiedToCurrentActivity {}
83+
7584 public interface NotificationOpenedHandler {
7685 /**
7786 * Callback to implement in your app to handle when a notification is
@@ -130,14 +139,17 @@ public interface PostNotificationResponseHandler {
130139 private static TrackGooglePurchase trackGooglePurchase ;
131140 private static TrackAmazonPurchase trackAmazonPurchase ;
132141
133- public static final String VERSION = "010900 " ;
142+ public static final String VERSION = "010901 " ;
134143
135144 private static PushRegistrator pushRegistrator ;
136145 private static AdvertisingIdentifierProvider mainAdIdProvider = new AdvertisingIdProviderGPS ();
137146
138147 private static int deviceType ;
139148 public static String sdkType = "native" ;
140149
150+ private static JSONObject nextInitAdditionalDataJSON = null ;
151+ private static String nextInitMessage = null ;
152+
141153 public static void init (Activity context , String googleProjectNumber , String oneSignalAppId ) {
142154 init (context , googleProjectNumber , oneSignalAppId , null );
143155 }
@@ -184,8 +196,23 @@ public static void init(Activity context, String googleProjectNumber, String one
184196 currentSubscription = -4 ;
185197 }
186198
187- if (initDone )
199+ if (initDone ) {
200+ if (context != null )
201+ appContext = context ;
202+ if (inNotificationOpenedHandler != null )
203+ notificationOpenedHandler = inNotificationOpenedHandler ;
204+
205+ onResumed ();
206+
207+ if (nextInitMessage != null && notificationOpenedHandler != null ) {
208+ fireNotificationOpenedHandler (nextInitMessage , nextInitAdditionalDataJSON , false );
209+
210+ nextInitMessage = null ;
211+ nextInitAdditionalDataJSON = null ;
212+ }
213+
188214 return ;
215+ }
189216
190217 // END: Init validation
191218
@@ -236,12 +263,16 @@ public void complete(String id) {
236263
237264 // Called from tapping on a Notification from the status bar when the activity is completely dead and not open in any state.
238265 if (appContext .getIntent () != null && appContext .getIntent ().getBundleExtra ("data" ) != null )
239- runNotificationOpenedCallback (appContext .getIntent ().getBundleExtra ("data" ), false , true );
266+ runNotificationOpenedCallback (appContext .getIntent ().getBundleExtra ("data" ), false );
240267
241268 if (TrackGooglePurchase .CanTrack (appContext ))
242269 trackGooglePurchase = new TrackGooglePurchase (appContext );
243270
244271 initDone = true ;
272+
273+ // In the future on Android 4.0 (API 14)+ devices use registerActivityLifecycleCallbacks
274+ // instead of requiring developers to call onPause and onResume in each activity.
275+ // Might be able to use registerOnActivityPausedListener in Android 2.3.3 (API 10) to 3.2 (API 13) for backwards compatibility
245276 }
246277
247278 private static void updateRegistrationId (String id ) {
@@ -784,7 +815,7 @@ static void sendPurchases(JSONArray purchases, boolean newAsExisting, ResponseHa
784815 }
785816 }
786817
787- private static void runNotificationOpenedCallback (final Bundle data , final boolean isActive , boolean isUiThread ) {
818+ private static void runNotificationOpenedCallback (final Bundle data , final boolean isActive ) {
788819 try {
789820 JSONObject customJSON = new JSONObject (data .getString ("custom" ));
790821
@@ -823,31 +854,43 @@ private static void runNotificationOpenedCallback(final Bundle data, final boole
823854 if (additionalDataJSON .equals (new JSONObject ()))
824855 additionalDataJSON = null ;
825856
826- final JSONObject finalAdditionalDataJSON = additionalDataJSON ;
827- Runnable callBack = new Runnable () {
828- @ Override
829- public void run () {
830- notificationOpenedHandler .notificationOpened (data .getString ("alert" ), finalAdditionalDataJSON , isActive );
831- }
832- };
857+ if (appContext .isFinishing ()
858+ && (notificationOpenedHandler .getClass ().isAnnotationPresent (TiedToCurrentActivity .class )
859+ || notificationOpenedHandler instanceof Activity )) {
833860
834- if (isUiThread )
835- callBack .run ();
836- else
837- appContext .runOnUiThread (callBack );
861+ // Activity is finished or isFinishing, run callback later when OneSignal.init is called again from anther Activity.
862+ nextInitAdditionalDataJSON = additionalDataJSON ;
863+ nextInitMessage = data .getString ("alert" );
864+ return ;
865+ }
866+
867+ fireNotificationOpenedHandler (data .getString ("alert" ), additionalDataJSON , isActive );
838868 }
839869 } catch (Throwable t ) {
840870 Log (LOG_LEVEL .ERROR , "Failed to run callback from notification opened." , t );
841871 }
842872 }
843873
874+ private static void fireNotificationOpenedHandler (final String message , final JSONObject additionalDataJSON , final boolean isActive ) {
875+ if (Looper .getMainLooper ().getThread () == Thread .currentThread ()) // isUIThread
876+ notificationOpenedHandler .notificationOpened (message , additionalDataJSON , isActive );
877+ else {
878+ appContext .runOnUiThread (new Runnable () {
879+ @ Override
880+ public void run () {
881+ notificationOpenedHandler .notificationOpened (message , additionalDataJSON , isActive );
882+ }
883+ });
884+ }
885+ }
886+
844887 // Called when receiving GCM message when app is open and in focus.
845888 static void handleNotificationOpened (Bundle data ) {
846889 sendNotificationOpened (appContext , data );
847- runNotificationOpenedCallback (data , true , false );
890+ runNotificationOpenedCallback (data , true );
848891 }
849892
850- // Called when opening a notification when the app is suspended in the background.
893+ // Called when opening a notification when the app is suspended in the background or when it is dead
851894 public static void handleNotificationOpened (Context inContext , Bundle data ) {
852895 sendNotificationOpened (inContext , data );
853896
@@ -885,7 +928,7 @@ public static void handleNotificationOpened(Context inContext, Bundle data) {
885928 }
886929
887930 if (initDone )
888- runNotificationOpenedCallback (data , false , false );
931+ runNotificationOpenedCallback (data , false );
889932 }
890933
891934 private static void sendNotificationOpened (Context inContext , Bundle data ) {
0 commit comments