From d40cc747bf96a20a751ca25eb755075c38bee6dd Mon Sep 17 00:00:00 2001 From: Stian Jensen Date: Mon, 11 Sep 2023 18:03:33 +0200 Subject: [PATCH] Update example app to use two activities Using singleTask in an Android application for the activity that has an intent-filter on the LAUNCHER, means that any activities running on top of this activity will disappear when the app's icon is pressed again from the launcher. This is a problem, because when confirming a SetupIntent or PaymentIntent, Stripe may need to present a web browser (its own activity) for verification with a customer's bank or similar, and the user may even need to leave this web browser activity temporarily to navigate to their bank's own application. If the user is not careful when navigating back to the original app, and taps the app's icon from the launcher, the app will open to its original activity, and the web browser is gone. Instead, the user will need to navigate back only using Android's app switcher, which will correctly bring you back into the open web browser activity. The change in this commit side-steps this issue by splitting the example application into two acitivites. One that is only responsible for launching the application, and a second activity that actually represents the react native application, and will be started by the first activity, ensuring to only start it once. This fixes #355. --- .../android/app/src/main/AndroidManifest.xml | 12 ++++++----- .../reactnativestripesdk/LaunchActivity.java | 20 +++++++++++++++++++ .../reactnativestripesdk/MainActivity.java | 12 +++++++++++ .../reactnativestripesdk/MainApplication.java | 15 ++++++++++++++ 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 example/android/app/src/main/java/com/example/reactnativestripesdk/LaunchActivity.java diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 851fba217..37436cdf3 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -15,6 +15,13 @@ + + + + + + + - - - - - diff --git a/example/android/app/src/main/java/com/example/reactnativestripesdk/LaunchActivity.java b/example/android/app/src/main/java/com/example/reactnativestripesdk/LaunchActivity.java new file mode 100644 index 000000000..e6bdfd730 --- /dev/null +++ b/example/android/app/src/main/java/com/example/reactnativestripesdk/LaunchActivity.java @@ -0,0 +1,20 @@ +package com.example.reactnativestripesdk; + +import android.os.Bundle; +import android.app.Activity; +import android.content.Intent; + +public class LaunchActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + MainApplication application = (MainApplication) getApplication(); + // check that MainActivity is not started yet + if (!application.isActivityInBackStack(MainActivity.class)) { + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + } + finish(); + } +} diff --git a/example/android/app/src/main/java/com/example/reactnativestripesdk/MainActivity.java b/example/android/app/src/main/java/com/example/reactnativestripesdk/MainActivity.java index c5a4437cd..e3cd04056 100644 --- a/example/android/app/src/main/java/com/example/reactnativestripesdk/MainActivity.java +++ b/example/android/app/src/main/java/com/example/reactnativestripesdk/MainActivity.java @@ -15,6 +15,18 @@ protected String getMainComponentName() { return "main"; } + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ((MainApplication) getApplication()).addActivityToStack(this.getClass()); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + ((MainApplication) getApplication()).removeActivityFromStack(this.getClass()); + } + /** * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and * you can specify the rendered you wish to use (Fabric or the older renderer). diff --git a/example/android/app/src/main/java/com/example/reactnativestripesdk/MainApplication.java b/example/android/app/src/main/java/com/example/reactnativestripesdk/MainApplication.java index bff08a508..da9009f26 100644 --- a/example/android/app/src/main/java/com/example/reactnativestripesdk/MainApplication.java +++ b/example/android/app/src/main/java/com/example/reactnativestripesdk/MainApplication.java @@ -12,6 +12,7 @@ import com.example.reactnativestripesdk.newarchitecture.MainApplicationReactNativeHost; import java.lang.reflect.InvocationTargetException; import java.util.List; +import java.util.ArrayList; import com.reactnativestripesdk.StripeSdkPackage; public class MainApplication extends Application implements ReactApplication { @@ -60,6 +61,20 @@ public void onCreate() { initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); // Remove this line if you don't want Flipper enabled } + private ArrayList runningActivities = new ArrayList<>(); + + public void addActivityToStack (Class cls) { + if (!runningActivities.contains(cls)) runningActivities.add(cls); + } + + public void removeActivityFromStack (Class cls) { + if (runningActivities.contains(cls)) runningActivities.remove(cls); + } + + public boolean isActivityInBackStack (Class cls) { + return runningActivities.contains(cls); + } + /** * Loads Flipper in React Native templates. *