From 3f4bb6207180124991fab8890f5453b9ef271e0f Mon Sep 17 00:00:00 2001 From: Amit Davidi Date: Wed, 16 Nov 2016 17:46:48 +0200 Subject: [PATCH] Extensibility refactor step 3: notification drawer & init-notification cleanup --- .../app/MainApplication.java | 2 +- .../RNNotificationsPackage.java | 11 ++- .../core/AppLaunchHelper.java | 4 +- .../core/INotificationsDrawerApplication.java | 5 ++ .../core/IPushNotificationsDrawer.java | 11 +++ .../core/InitialNotification.java | 4 ++ .../core/PushNotification.java | 7 +- .../core/PushNotificationsDrawer.java | 51 ++++++++++++++ .../core/RNNotificationsModule.java | 69 +++++++++++++++---- .../core/ReactAppLifecycleFacade.java | 11 ++- example/index.android.js | 38 ++++++++-- 11 files changed, 179 insertions(+), 34 deletions(-) create mode 100644 example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/INotificationsDrawerApplication.java create mode 100644 example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/IPushNotificationsDrawer.java create mode 100644 example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/PushNotificationsDrawer.java diff --git a/example/android/myapplication/src/main/java/com/wix/reactnativenotifications/app/MainApplication.java b/example/android/myapplication/src/main/java/com/wix/reactnativenotifications/app/MainApplication.java index fc8df00..350b838 100644 --- a/example/android/myapplication/src/main/java/com/wix/reactnativenotifications/app/MainApplication.java +++ b/example/android/myapplication/src/main/java/com/wix/reactnativenotifications/app/MainApplication.java @@ -23,7 +23,7 @@ public class MainApplication extends Application implements ReactApplication { protected List getPackages() { return Arrays.asList( new MainReactPackage(), - new RNNotificationsPackage() + new RNNotificationsPackage(MainApplication.this) ); } }; diff --git a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java index 215308a..e8495c4 100644 --- a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java +++ b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java @@ -1,5 +1,7 @@ package com.wix.reactnativenotifications; +import android.app.Application; + import com.facebook.react.ReactPackage; import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.bridge.NativeModule; @@ -13,9 +15,16 @@ import java.util.List; public class RNNotificationsPackage implements ReactPackage { + + final Application mApplication; + + public RNNotificationsPackage(Application application) { + mApplication = application; + } + @Override public List createNativeModules(ReactApplicationContext reactContext) { - return Arrays.asList(new RNNotificationsModule(reactContext)); + return Arrays.asList(new RNNotificationsModule(mApplication, reactContext)); } @Override diff --git a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/AppLaunchHelper.java b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/AppLaunchHelper.java index af7cfb8..b098e7c 100644 --- a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/AppLaunchHelper.java +++ b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/AppLaunchHelper.java @@ -34,7 +34,9 @@ public class AppLaunchHelper { public static boolean isLaunchIntentsActivity(Activity activity) { final Intent helperIntent = activity.getPackageManager().getLaunchIntentForPackage(activity.getPackageName()); - return activity.getLocalClassName().equals(helperIntent.getComponent().getClassName()); + final String activityName = activity.getComponentName().getClassName(); + final String launchIntentActivityName = helperIntent.getComponent().getClassName(); + return activityName.equals(launchIntentActivityName); } public static boolean isLaunchIntent(Intent intent) { diff --git a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/INotificationsDrawerApplication.java b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/INotificationsDrawerApplication.java new file mode 100644 index 0000000..13cffc7 --- /dev/null +++ b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/INotificationsDrawerApplication.java @@ -0,0 +1,5 @@ +package com.wix.reactnativenotifications.core; + +public interface INotificationsDrawerApplication { + IPushNotificationsDrawer getPushNotificationsDrawer(); +} diff --git a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/IPushNotificationsDrawer.java b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/IPushNotificationsDrawer.java new file mode 100644 index 0000000..13a1b30 --- /dev/null +++ b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/IPushNotificationsDrawer.java @@ -0,0 +1,11 @@ +package com.wix.reactnativenotifications.core; + +import android.app.Activity; + +public interface IPushNotificationsDrawer { + void onAppInit(); + void onAppVisible(); + void onNewActivity(Activity activity); + + void onNotificationOpened(); +} diff --git a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/InitialNotification.java b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/InitialNotification.java index 4b02ad2..499d6cf 100644 --- a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/InitialNotification.java +++ b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/InitialNotification.java @@ -9,6 +9,10 @@ public class InitialNotification { sNotification = pushNotificationProps; } + public static void clear() { + sNotification = null; + } + @Nullable public static PushNotificationProps get() { return sNotification; diff --git a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/PushNotification.java b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/PushNotification.java index b630c73..176cb56 100644 --- a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/PushNotification.java +++ b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/PushNotification.java @@ -58,7 +58,7 @@ public class PushNotification implements IPushNotification { @Override public void onOpened() { digestNotification(); - deleteAllPostedNotifications(); + PushNotificationsDrawer.get(mContext).onNotificationOpened(); } @Override @@ -170,9 +170,4 @@ public class PushNotification implements IPushNotification { final Intent intent = AppLaunchHelper.getLaunchIntent(mContext); mContext.startActivity(intent); } - - protected void deleteAllPostedNotifications() { - final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancelAll(); - } } diff --git a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/PushNotificationsDrawer.java b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/PushNotificationsDrawer.java new file mode 100644 index 0000000..6aedd99 --- /dev/null +++ b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/PushNotificationsDrawer.java @@ -0,0 +1,51 @@ +package com.wix.reactnativenotifications.core; + +import android.app.Activity; +import android.app.NotificationManager; +import android.content.Context; + +public class PushNotificationsDrawer implements IPushNotificationsDrawer { + + protected final Context mContext; + + public PushNotificationsDrawer(Context context) { + mContext = context; + } + + public static IPushNotificationsDrawer get(Context context) { + final Context appContext = context.getApplicationContext(); + if (appContext instanceof INotificationsDrawerApplication) { + return ((INotificationsDrawerApplication) appContext).getPushNotificationsDrawer(); + } + + return new PushNotificationsDrawer(context); + } + + @Override + public void onAppInit() { + clearAll(); + } + + @Override + public void onAppVisible() { + clearAll(); + } + + @Override + public void onNewActivity(Activity activity) { + if (AppLaunchHelper.isLaunchIntentsActivity(activity) && + !AppLaunchHelper.isLaunchIntent(activity.getIntent())) { + InitialNotification.clear(); + } + } + + @Override + public void onNotificationOpened() { + clearAll(); + } + + protected void clearAll() { + final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancelAll(); + } +} diff --git a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/RNNotificationsModule.java b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/RNNotificationsModule.java index c6fa5ea..6e554cb 100644 --- a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/RNNotificationsModule.java +++ b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/RNNotificationsModule.java @@ -1,7 +1,10 @@ package com.wix.reactnativenotifications.core; +import android.app.Activity; +import android.app.Application; import android.content.Context; import android.content.Intent; +import android.os.Bundle; import android.util.Log; import com.facebook.react.bridge.Arguments; @@ -13,12 +16,14 @@ import com.wix.reactnativenotifications.gcm.GcmInstanceIdRefreshHandlerService; import static com.wix.reactnativenotifications.Defs.LOGTAG; -public class RNNotificationsModule extends ReactContextBaseJavaModule { +public class RNNotificationsModule extends ReactContextBaseJavaModule implements AppLifecycleFacade.AppVisibilityListener, Application.ActivityLifecycleCallbacks { - public RNNotificationsModule(ReactApplicationContext reactContext) { + public RNNotificationsModule(Application application, ReactApplicationContext reactContext) { super(reactContext); - ReactAppLifecycleFacade.get().onAppInit(reactContext); + ReactAppLifecycleFacade.get().init(reactContext); + ReactAppLifecycleFacade.get().addVisibilityListener(this); + application.registerActivityLifecycleCallbacks(this); } @Override @@ -29,14 +34,17 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule { @Override public void initialize() { Log.d(LOGTAG, "Native module init"); + startGcmIntentService(GcmInstanceIdRefreshHandlerService.EXTRA_IS_APP_INIT); - final Context appContext = getReactApplicationContext().getApplicationContext(); - final Intent tokenFetchIntent = new Intent(appContext, GcmInstanceIdRefreshHandlerService.class); - tokenFetchIntent.putExtra(GcmInstanceIdRefreshHandlerService.EXTRA_IS_APP_INIT, true); - appContext.startService(tokenFetchIntent); + IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(getReactApplicationContext().getApplicationContext()); + notificationsDrawer.onAppInit(); } - + @ReactMethod + public void refreshToken() { + Log.d(LOGTAG, "Native method invocation: refreshToken()"); + startGcmIntentService(GcmInstanceIdRefreshHandlerService.EXTRA_MANUAL_REFRESH); + } @ReactMethod public void getInitialNotification(final Promise promise) { @@ -55,13 +63,50 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule { } } - @ReactMethod - public void refreshToken() { - Log.d(LOGTAG, "Native method invocation: refreshToken()"); + @Override + public void onAppVisible() { + IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(getReactApplicationContext().getApplicationContext()); + notificationsDrawer.onAppVisible(); + } + + @Override + public void onAppNotVisible() { + } + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(getReactApplicationContext().getApplicationContext()); + notificationsDrawer.onNewActivity(activity); + } + + @Override + public void onActivityStarted(Activity activity) { + } + + @Override + public void onActivityResumed(Activity activity) { + } + + @Override + public void onActivityPaused(Activity activity) { + } + + @Override + public void onActivityStopped(Activity activity) { + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + } + + @Override + public void onActivityDestroyed(Activity activity) { + } + protected void startGcmIntentService(String extraFlag) { final Context appContext = getReactApplicationContext().getApplicationContext(); final Intent tokenFetchIntent = new Intent(appContext, GcmInstanceIdRefreshHandlerService.class); - tokenFetchIntent.putExtra(GcmInstanceIdRefreshHandlerService.EXTRA_MANUAL_REFRESH, true); + tokenFetchIntent.putExtra(extraFlag, true); appContext.startService(tokenFetchIntent); } } diff --git a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/ReactAppLifecycleFacade.java b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/ReactAppLifecycleFacade.java index f1d6639..26ef28f 100644 --- a/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/ReactAppLifecycleFacade.java +++ b/example/android/reactnativenotification/src/main/java/com/wix/reactnativenotifications/core/ReactAppLifecycleFacade.java @@ -12,7 +12,7 @@ import static com.wix.reactnativenotifications.Defs.LOGTAG; public class ReactAppLifecycleFacade implements AppLifecycleFacade { - private static ReactAppLifecycleFacade sInstance = new ReactAppLifecycleFacade(); + private static final ReactAppLifecycleFacade sInstance = new ReactAppLifecycleFacade(); private ReactContext mReactContext; private boolean mIsVisible; @@ -22,10 +22,8 @@ public class ReactAppLifecycleFacade implements AppLifecycleFacade { return sInstance; } - public synchronized void onAppInit(ReactContext reactContext) { + public void init(ReactContext reactContext) { mReactContext = reactContext; - mIsVisible = false; - reactContext.addLifecycleEventListener(new LifecycleEventListener() { @Override public void onHostResume() { @@ -35,15 +33,14 @@ public class ReactAppLifecycleFacade implements AppLifecycleFacade { @Override public void onHostPause() { + Log.d(LOGTAG, "onHostPause"); switchToInvisible(); } @Override public void onHostDestroy() { - switchToInvisible(); Log.d(LOGTAG, "onHostDestroy"); - mReactContext.removeLifecycleEventListener(this); - mReactContext = null; + switchToInvisible(); } }); } diff --git a/example/index.android.js b/example/index.android.js index c63a5d3..e6e9d55 100644 --- a/example/index.android.js +++ b/example/index.android.js @@ -11,6 +11,30 @@ import { import {NotificationsAndroid, PendingNotifications} from './notifications'; +let mainScreen; + +function onPushRegistered() { + if (mainScreen) { + mainScreen.onPushRegistered(); + } +} + +function onNotificationOpened(notification) { + if (mainScreen) { + mainScreen.onNotificationOpened(notification) + } +} + +function onNotificationReceived(notification) { + if (mainScreen) { + mainScreen.onNotificationReceived(notification) + } +} + +NotificationsAndroid.setRegistrationTokenUpdateListener(onPushRegistered); +NotificationsAndroid.setNotificationOpenedListener(onNotificationOpened); +NotificationsAndroid.setNotificationReceivedListener(onNotificationReceived); + const styles = StyleSheet.create({ container: { flex: 1, @@ -36,22 +60,24 @@ class MainComponent extends Component { this.state = { elapsed: 0, lastNotification: undefined - } - } + }; - componentWillMount() { - NotificationsAndroid.setRegistrationTokenUpdateListener(this.onPushRegistered.bind(this)); - NotificationsAndroid.setNotificationOpenedListener(this.onNotificationOpened.bind(this)); - NotificationsAndroid.setNotificationReceivedListener(this.onNotificationReceived.bind(this)); + console.log('ReactScreen', 'ReactScreen'); + mainScreen = this; } componentDidMount() { + console.log('ReactScreen', 'componentDidMount'); setInterval(this.onTick.bind(this), 1000); PendingNotifications.getInitialNotification() .then((notification) => {console.log("getInitialNotification:", notification); this.setState({initialNotification: notification.getData()});}) .catch((err) => console.error("getInitialNotifiation failed", err)); } + componentWillUnmount() { + console.log('ReactScreen', 'componentWillUnmount'); + } + onTick() { this.setState({elapsed: this.state.elapsed + 1}); } -- 2.26.2