Restore, Reset and Log Out of Applications Using the Jetpack Flows Component
- How to handle application restore and passcode timeouts using the Jetpack Compose Flows component
- How to reset an application using the Jetpack Compose Flows component
- How to log out of an application using the Jetpack Compose Flows component
- How to delete the user registration of an application using the Jetpack Compose Flows component
Prerequisites
- You have Set Up a BTP Account for Tutorials. Follow the instructions to get an account, and then to set up entitlements and service instances for the following BTP services.
- SAP Mobile Services
- You completed Try Out the SAP BTP SDK Wizard for Android.
- You completed Get Familiar with Jetpack Compose Flows Component by a Wizard-Generated Application.
- You completed Customize the Jetpack Compose Onboarding Flow.
- Step 1
After onboarding, the next time users open the mobile app, the restore flow will be started. Basically, the restore flow consists of the screen unlocking the app with either the passcode or biometric information, if enabled. The restore flow will also check whether the passcode is expired based on the setting defined in the passcode policy. If the passcode is expired, the restore flow will ask the user to create a new passcode and launch a change passcode flow.
Similar to the onboarding flow, the restore flow will also listen to the flow states and notify corresponding events to the client code.
The flows component will automatically determine whether to use the onboarding or restore flow, so the app can use the same client code for both flows.
-
Open the project you previously created using the SAP BTP SDK Wizard for Android.
-
In Android Studio, on Windows, press
Ctrl+N, or, on a Mac, presscommand+O, and typeWelcomeActivityto openWelcomeActivity.kt. -
On Windows, press
Ctrl+F12, or, on a Mac, presscommand+F12, and typestartOnboardingto move to thestartOnboardingmethod. As we mentioned in Get Familiar with Jetpack Compose Flows Component by a Wizard-Generated Application, this method starts an onboarding flow. After onboarding, the next time the app starts, the same method is called and the Flows component detects that the user is already onboarded and starts the restore flow. The client code does not need handle the logic to explicitly start a restore flow.
KotlinCopyfun startOnboarding(context: Context, appConfig: AppConfig) { TimeoutLockService.updateApplicationLockState(true) WelcomeActivity.logger.debug("Before starting flow, lock state: {}", ApplicationStates.applicationLocked) FlowUtil.startFlow( context, flowContext = getOnboardingFlowContext(context, appConfig) ) { resultCode, data -> if (resultCode == Activity.RESULT_OK) { onlineInitializationAfterOnboarding(context) { launchMainBusinessActivity(context) } WelcomeActivity.logger.debug("After flow, lock state: {}", ApplicationStates.applicationLocked) } else { startOnboarding(context, appConfig) } } } -
The restore flow will notify the same events as the onboarding flow and one additional
UnlockWithPasscodeevent, which is specific to the restore flow. When the app is unlocked using a passcode, the client code can get the passcode from theonUnlockWithPasscodecallback of theFlowStateListenerinstance and open the secure store. Customize the Jetpack Compose Onboarding Flow explains the events notified in the onboarding flow. -
When the app is put to background, the Flows component will monitor whether the passcode is timed out based on the “Lock Timeout” value defined in the passcode policy. When the passcode is timed out and the app is put to foreground again, a timeout unlock flow will be started. This is the
FlowType.TimeoutUnlockflow type, which is used internally by the Flows component for the passcode timeout scenario. This flow’s function is exactly the same as that of the restore flow.
-
- Step 2
There may be occasions when the user wants to reset the app to its initial state. The reset flow is designed to clear all the application data, user data, and security data managed by the Flows component.
-
Open the project you previously created using the SAP BTP SDK Wizard for Android.
-
In Android Studio, on Windows, press
Ctrl+N, or, on a Mac, presscommand+O, and typeSettingsScreento openSettingsScreen.kt. -
On Windows, press
Ctrl+F12, or, on a Mac, presscommand+F12, and typestartResetAppFlowto move to thestartResetAppFlowmethod. To start the flow to reset the application, set the flow type toFlowType.Resetfor theFlowContextinstance, and then start the flow with thisFlowContextinstance. The entire process to reset the application will be handled automatically.
KotlinCopyprivate fun startResetAppFlow(context: Context) { FlowUtil.startFlow( context = context, flowContext = FlowContextRegistry.flowContext.copy( flowType = FlowType.Reset, flow = null ) ) { resultCode, _ -> if (resultCode == Activity.RESULT_OK) { launchWelcomeActivity(context) } } } -
When the reset flow is started, the default behavior is for a dialog to be displayed, asking the user for confirmation.

You can customize your client code so that the reset flow hides this dialog by setting the
skipparameter totruefor the bundleskipConfirmForResetFlowand populating this customized bundle with theupdateIntentparameter to start the reset flow.KotlinCopyFlowUtil.startFlow( context = context, flowContext = FlowContextRegistry.flowContext.copy( flowType = FlowType.Reset, flow = null ), updateIntent = { intent -> intent.populateCustomBundle { skipConfirmForResetFlow(skip = true) } } ) { resultCode, _ -> if (resultCode == Activity.RESULT_OK) { launchWelcomeActivity(context) } } -
Before removing all the data managed by the Flows component, the reset flow will notify the
ApplicationResetevent. You can use theonApplicationResetcallback of theFlowStateListenerinstance to insert its own logic for application reset, for example to clear the data managed by the client code and reset the mobile services added to the application.In Android Studio, on Windows, press
Ctrl+N, or, on a Mac, presscommand+O, and typeWizardFlowStateListenerto openWizardFlowStateListener.kt. On Windows, pressCtrl+F12, or, on a Mac, presscommand+F12, and typeonApplicationResetto move to theonApplicationResetmethod.
KotlinCopyoverride suspend fun onApplicationReset() { this.application.resetApplication() }
-
- Step 3
The logout flow will try to log out the current user if the network is available, then remove the OAuth2 token of the current user if the app is authenticated with OAuth2. No matter the network is available or not, after the flow, the user needs to be authenticated again when making an API call to the server.
-
Open the project you previously created using the SAP BTP SDK Wizard for Android.
-
In Android Studio, on Windows, press
Ctrl+N, or, on a Mac, presscommand+O, and typeEntitySetsScreento openEntitySetsScreen.kt. -
On Windows, press
Ctrl+F12, or, on a Mac, presscommand+F12, and typeStartLogoutFlowto move to theStartLogoutFlowmethod. To start the flow to log out of the application, set the flow type toFlowType.Logoutfor theFlowContextinstance, and then start the flow with thisFlowContextinstance.
KotlinCopyfun StartLogoutFlow() { val context = LocalContext.current FlowUtil.startFlow( context = context, flowContext = FlowContextRegistry.flowContext.copy( flowType = FlowType.Logout, flow = null ) ) { resultCode, _ -> if (resultCode == Activity.RESULT_OK) { launchWelcomeActivity(context) } } } -
When the logout flow is started, the default behavior is for a dialog to be displayed, asking the user for confirmation.

You can customize your client code so that the logout flow hides this dialog by setting the
skipparameter totruefor the bundleskipConfirmForLogoutFlowand populating this customized bundle with theupdateIntentparameter to start the logout flow.KotlinCopyFlowUtil.startFlow( context = context, flowContext = FlowContextRegistry.flowContext.copy( flowType = FlowType.Logout, flow = null ), updateIntent = { intent -> intent.populateCustomBundle { skipConfirmForLogoutFlow(skip = true) } } ) { resultCode, _ -> if (resultCode == Activity.RESULT_OK) { launchWelcomeActivity(context) } } -
The logout flow will not automatically remove the push registration. The client code can implement the
FlowActivityResultCallbackcallback function to delete the Firebase push token if it does not want to receive push notifications after logout. The logout flow will trigger the callback function after a successful logout.KotlinCopyFlowUtil.startFlow( context = context, flowContext = FlowContextRegistry.flowContext.copy( flowType = FlowType.Logout, flow = null ) ) { resultCode, _ -> if (resultCode == Activity.RESULT_OK) { SDKInitializer.getService(FirebasePushService::class)?.stopPush() } }
-
- Step 4
The delete registration flow will delete the registration of the current user on a device. This flow is only for multiple user modes. For a single user mode app, the reset flow is used instead. For offline apps, the client code needs to make sure that the current user’s data is synchronized to the server before calling this flow.
-
Open the project you previously created using the SAP BTP SDK Wizard for Android.
-
In Android Studio, on Windows, press
Ctrl+N, or, on a Mac, presscommand+O, and typeEntitySetsScreento openEntitySetsScreen.kt. -
On Windows, press
Ctrl+F12, or, on a Mac, presscommand+F12, and typestartDeleteRegFlowto move to thestartDeleteRegFlowmethod. To start the flow to log out of the application, set the flow type toFlowType.DeleteRegistrationfor theFlowContextinstance, and then start the flow with thisFlowContextinstance.
KotlinCopyprivate fun startDeleteRegFlow(context: Context, finishCallback: (Int)-> Unit = {}) { FlowUtil.startFlow( context = context, flowContext = FlowContextRegistry.flowContext.copy( flowType = FlowType.DeleteRegistration, flow = null ) ) { resultCode, _ -> finishCallback(resultCode) if (resultCode == Activity.RESULT_OK) { launchWelcomeActivity(context) } } } -
When the delete registration flow is started, the default behavior is for a dialog to be displayed, asking the user for confirmation.

You can customize your client code so that the delete registration flow hides this dialog by setting the
skipparameter totruefor theskipConfirmForDeleteRegistrationFlowbundle and populating this customized bundle with the parameterupdateIntentto start the delete registration flow.KotlinCopyFlowUtil.startFlow( context = context, flowContext = FlowContextRegistry.flowContext.copy( flowType = FlowType.DeleteRegistration, flow = null ), updateIntent = { intent -> intent.populateCustomBundle { skipConfirmForDeleteRegistrationFlow(skip = true) } } ) { resultCode, _ -> if (resultCode == Activity.RESULT_OK) { launchWelcomeActivity(context) } }
Congratulations! You now have learned how to restore, reset, logout and delete the user registration of an application using the Jetpack Compose Flows component!
-