Android - Deep Linking
Overview
Deep linking enables direct navigation to specific screens or content within the Q2 Mobile App. This functionality allows external sources and other native modules to programmatically route users to any existing URL path in the application.
Since the app's primary interface is web-based, deep linking essentially allows you to load specific web pages or application states directly, bypassing the need for users to manually navigate through the app's interface.
Deep Linking Methods
The Q2 Mobile App provides two primary approaches for implementing deep links:
- ACTION_VIEW Intent - Using Android's standard intent system
- sdkUtils Functions - Using our custom SDK utility methods
Using ACTION_VIEW Intent
The Q2 Mobile App includes a built-in deep linking mechanism that responds to ACTION_VIEW
intents.
When triggered, these intents are processed by the MainActivity
, which attempts to navigate to the
specified path using the app's internal routing system.
Intent Schema
The deep linking intent follows a specific URI schema that must be constructed correctly. You can use this to create the intent:
private fun setupScheme(context: Context, uri: String? = null): Intent {
var intentScheme = "app://${context.packageName}/open"
if (uri != null) {
intentScheme += "#$uri"
}
return Intent(Intent.ACTION_VIEW, Uri.parse(intentScheme))
}
// Usage example
val intent = setupScheme(context, remoteMessage.data[myUriKey])
sdkUtils.getActivity()?.startActivity(intent)
How It Works
- Intent Creation: An
ACTION_VIEW
intent is created with the properly formatted URI - URI Structure: The URI follows the pattern
app://${context.packageName}/open#${path}
- Processing: The
MainActivity
receives the intent and processes the deep link - Navigation: The app navigates to the specified path within the webview
Using sdkUtils Functions
Alternatively, you can use the SDK's built-in utility functions for more direct control over deep linking. The SDK provides two specialized functions depending on the user's authentication state:
// For authenticated users or paths requiring authentication
sdkUtils.loadPathInUuxViewAfterLogon(uri)
// For pre-authentication navigation within the webview
sdkUtils.loadPathInUuxViewBeforeLogon(uri)
Function Differences
Function | Usage Context | Behavior |
---|---|---|
loadPathInUuxViewAfterLogon() | Post-authentication or auth-required paths | Waits for user authentication before navigation. Use this when in doubt. |
loadPathInUuxViewBeforeLogon() | Pre-authentication, within webview only | Only works before authentication and when already in the webview context. |
When uncertain about which function to use, choose loadPathInUuxViewAfterLogon()
as it handles
most scenarios reliably.
URI Formatting Requirements
The URI must be formatted exactly as specified below. Incorrect formatting will prevent deep linking from working entirely.
Required URI Format
- ✅ DO: Start at the root of the sub-path
- ❌ DON'T: Include the base URL
- ❌ DON'T: Start with
#
or/
- ✅ DO: Ensure the URL is valid and sanitized
Valid URI Examples
// ✅ Correct formats
"messages"
"extension/YourExtension/File"
"extension/YourOtherExtension"
"settings/profile"
// ❌ Incorrect formats
"/messages" // Don't start with /
"#messages" // Don't start with #
"https://app.com/messages" // Don't include base URL
"/extension/YourExtension" // Don't start with /
Finding the Correct URI
If you're unsure about the correct URI format for a specific page:
- Navigate to the target location using a mobile browser
- Copy the URL from the browser's address bar
- Remove the base URL (everything before the path)
- Remove any prefixed
#
or/
characters - Use the remaining path as your URI parameter
Example URL Conversion
Original URL: https://yourapp.com/#/messages/
Correct URI: messages/
Best Practices
URI Validation
Always validate and sanitize your URIs before using them in deep links:
fun sanitizeUri(uri: String?): String? {
return uri?.let {
it.removePrefix("/")
.removePrefix("#")
.trim()
.takeIf { sanitized -> sanitized.isNotEmpty() }
}
}
// Usage
val cleanUri = sanitizeUri(rawUri)
if (cleanUri != null) {
sdkUtils.loadPathInUuxViewAfterLogon(cleanUri)
}
Error Handling
Implement proper error handling for deep linking operations:
try {
val intent = setupScheme(context, uri)
sdkUtils.getActivity()?.startActivity(intent)
} catch (e: Exception) {
// Handle deep linking failure. Do not force crashes
Log.e("DeepLink", "Failed to open deep link: ${e.message}")
}
Testing Deep Links
- Test deep links with various URI formats to ensure robustness
- Verify behavior in both authenticated and unauthenticated states
- Test on different Android versions and device configurations
- Validate that invalid URIs are handled gracefully
- URI formatting is critical for successful deep linking
- Always sanitize and validate URIs before use
- Test deep links thoroughly in your target environment
- Consider the user's authentication state when choosing the appropriate method