I am using navcomponent deeplink option to deeplink from a universal link to my app screen.
Step 1 : added the deeplink param in main_nav_graph file
Step 2: added to manifest file of my mainactivity
Step 3: clicked on the link on a SMS to launch the deeplink
Scenarios seen:
in my app SplashActivity is the Main Launcher . But Main Activity is where navgraph is initialised. So i added the navgraph tag for main activity in Manifest
Main Activity is added as single task.
Now when i deeplink i see :
my mainactivity is resumed 2 times ( looks like app launch then close then launch again and deeplink to the screen)
If user is not logged in, i have a condition check to stay at navigation root view. But i see that it still navigates to the deeplink screen creating abnormal scenario.
As per the Navigation 2.1.0-alpha06 release notes:
Navigation now suppresses the animation that occurs when recreating the activity when handling a deep link, fixing a visual flash. (b/130362979)
So you should upgrade to Navigation 2.1.0 (currently 2.1.0-rc01 to fix the visual glitch).
Secondly, as per the conditional navigation documentation, you should not be using the login screen as the root of your graph. Instead, every destination that requires login should redirect users to the login screen if the user is not logged in. This is precisely to avoid the case you are experiencing: you want the user to be immediately sent to the correct deep linked screen with the correct back stack.
Related
I have single activity and multiple fragments using android navigation component. I am using implicit deep link of navigation component. The uri I get from email, when clicked, creates another app instance so the app stack looks like
My app (Instance1)
|
Email app(eg gmail)(clicked on link)
|
My app (Instance2)
What I want is to have single instance and cleared fragment backstack. I have already tried activity launchModes as "singleTop" and "singleInstance". They do keep the single app instance but my deeplink navigation didn't work in that case. Even after clicking the link, app was on top but there was no navigation, I am still seeing the fragment from where I left and not the destination of deeplink.
So let's say I have 3 types of activities, each with their own manifest file and intent filter:
HomeActivity
ProfileActivity - (deeplink url path: /profile-view)
SearchActivity - (deeplink url path: /search-view)
In my app, users can deep link into the ProfileActivity or SearchActivity directly via intent-filters. However, when this happens, there is no HomeActivity in the backstack. I want to ensure the HomeActivity is launched in the backstack whenever a non-Homeactivity is launched. How can I do that?
I was thinking of somehow checking if HomeActivity exists, and if it doesn't exist, launch that first?
Take a look into Android Navigation Component. This library handle's deep links gracefully. Take a look at here: Create a deep link for a destination.
When a user opens your app via an explicit deep link, the task back stack is cleared and replaced with the deep link destination. When nesting graphs, the start destination from each level of nesting—that is, the start destination from each element in the hierarchy—is also added to the stack. This means that when a user presses the Back button from a deep link destination, they navigate back up the navigation stack just as though they entered your app from its entry point.
I have start authorization screen, I want the user to log in every time the application starts, even onResume
In onResume() of your Activity navigate to your authorization screen. We want to use a kind of navigation that can be used from any fragment, so the best option would be the navigate(deepLink) method.
Add a DeepLink to the AuthorizationFragment in your navigation.xml:
<deepLink
android:id="#+id/deepLink"
app:uri="http://www.example.com/authorization" />
In Activity onResume()
findNavController(R.id.container).navigate("http://www.example.com/authorization")
If the destination is reachable from current NavGraph, it will navigate there.
Dismiss the authorization screen simply by calling NavController.navigateUp() from the authorization screen.
See documentation:
Navigate to a destination with Navigation Component using URI
How to create an implicit deep link
When I open the app from a deeplink (user clicks on URL) and press back button I expect user to navigate to a previous fragment in my navigation graph but it just exits the app.
The documentation says that back navigation should work the same way as if it the user got to that screen naturally.
Can I somehow specify the desired backstack in my navigation graph? Or can be backstack formed automatically after a deeplink? For older version of the library I found out that after back press it should navigate to the root of my navigation graph but that does not happen.
I’m using the navigation library from Android architecture components (version 1.0.0-beta01).
I found out what's going on here, for explicit deep links its supposed to go to a new back stack which is what you app would have if a user had naturally navigated to the view not the existing back stack (existing stack is cleared.
When a user opens your app via an explicit deep link, the task back stack is cleared and replaced with the deep link destination. When nesting graphs, the start destination from each level of nesting—that is, the start destination from each element in the hierarchy—is also added to the stack. This means that when a user presses the Back button from a deep link destination, they navigate back up the navigation stack just as though they entered your app from its entry point.
For implicit its a bit strange. You can make it do what explicit does but setting Intent.FLAG_ACTIVITY_NEW_TASK otherwise the back button and the navigation up button do two separate things:
The back button will do as you might expect, it will go back in your apps existing back stack and load that fragment.
The up button however will clear the a back stack and make a new one as if it was an explicit link.
If the flag is not set, you remain on the task stack of the previous app where the implicit deep link was triggered. In this case, the Back button takes you back to the previous app, while the Up button starts your app's task on the hierarchical parent destination within your navigation graph.kquote
Source: Android Documentation
As describe here back button should return to the previous fragment, you can set it manually in Java like this: button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_fragment, null));
In Kotlin like that: button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_fragment, null))
The Android system maintains a back stack containing the last visited destination. The first destination of your app is placed on the stack when the user opens the app. Each call to the navigate() method puts another destination on the top of the stack. Conversely, pressing the Up or Back button calls the NavController.navigateUp() and NavController.popBackStack() methods, respectively, to pop the top destination off of the stack.
Make sure that you are using NavHostFragment and not <fragment> in your hosting fragment activity.
I have 3 Activities: Main, Login, Wizard.
For each Activity I have separate Navigation Graph with fragment destinations.
Main Nav Graph has also Login Activity destination to launch Login screen on logout.
App seems to work correctly when launched from Action.MAIN launcher intent.
BUT I experience problem when using Deep Link. I would like to add URI to Login Nav Graph (Change Password Fragment). This Nav Graph uses separate NavHostFragment. I have used 2 approaches.
Directly add Deep Link to Change Password Fragment Destination in Login Nav Graph -> Deep Links navigate only to START DESTINATION (Login Fragment Destination). Here also Back button does NOT work correctly, i.e. finishing app instead returning to Main Nav Graph Main Destination.
Add Deep Link to Login Activity Destination in Main Nav Graph and again and here Back button does work correctly, I as expected landed on Login Fragment Destination. BUT here I want to manually navigate to Change Password Fragment Destination and I experience another problem, i.e. the Intent Action.View with Uri data is not delivered into this Login Activity destination. It is only delivered to Main Activity which host Main Nav Graph.
To sum up. I think this Deep link behaviour between multiple Nav Graphs connected by Activity Destinations does NOT work as it should. I do not know whether there are any solutions to this.
Can I retrieve Deep Link Arguments (Uri data) from NavController somehow? Or the only solution is to get it from getIntent().data? Here as I say this Intent is not forwarded to final destination Activity, but only to first Activity in the created stack of Activities.
Now I returned to manually handling Deep Links without Android Navigation Architecture as it seems useless if there is more complex navigation structure than single Nav Graph with single Activity and only inner Fragment navigation.