Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements a dual-intent fallback approach to fix Bolt deep link issues on Android. The solution first opens the Bolt app using a custom bolt:// scheme, then sends an HTTPS deep link to set the destination properly.
Changes:
- Added new
createBoltDeepLinkWebfunction in MainViewModel that generates HTTPS deep links for Bolt - Modified
createBoltDeepLinkto use thebolt://scheme for opening the app - Updated
openInSplitScreenin MainActivity to implement dual-intent logic with delayed execution
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
| MainViewModel.kt | Added createBoltDeepLinkWeb function for HTTPS deep links; modified createBoltDeepLink to use bolt:// scheme; updated prepareDeepLinks signature |
| CompareScreen.kt | Updated function signature to pass the new boltDeepLinkWeb parameter through the callback chain |
| MainActivity.kt | Implemented dual-intent logic to open Bolt app first, then send web deep link after delay |
| try { | ||
| // Open Bolt deep link | ||
| val boltIntent = Intent(Intent.ACTION_VIEW, Uri.parse(boltDeepLink)) | ||
| boltIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | ||
| boltIntent.setPackage("ee.mtakso.client") | ||
| startActivity(boltIntent) | ||
|
|
||
| kotlinx.coroutines.delay(SPLIT_SCREEN_DELAY_MS) | ||
|
|
||
| val boltIntentWeb = Intent(Intent.ACTION_VIEW, Uri.parse(boltDeepLink)) | ||
| boltIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | ||
| boltIntent.setPackage("ee.mtakso.client") | ||
| startActivity(boltIntent) | ||
|
|
There was a problem hiding this comment.
The new dual-intent logic for opening Bolt (opening the app first, then sending the web deep link) lacks test coverage. Since the repository has comprehensive test coverage for MainActivity (see MainActivityTest.kt), tests should be added to verify the correct sequence of intents, proper delays, and error handling for the Bolt app opening flow.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
| internal fun createBoltDeepLinkWeb( | ||
| pickup: String, | ||
| dropoff: String, | ||
| pickupCoords: Pair<Double, Double>?, | ||
| dropoffCoords: Pair<Double, Double>? | ||
| ): String { | ||
| Log.d("MainViewModel, ", "pickup: $pickup, dropoff: $dropoff, pickupCoords: $pickupCoords, dropoffCoords: $dropoffCoords") | ||
| return if (pickupCoords != null && dropoffCoords != null) { | ||
| // Format coordinates with exactly 6 decimal places to ensure compatibility with Bolt API | ||
| // Using Locale.US to ensure consistent decimal separator (period, not comma) | ||
| val pickupLat = String.format(Locale.US, "%.6f", pickupCoords.first) | ||
| val pickupLng = String.format(Locale.US, "%.6f", pickupCoords.second) | ||
| val dropoffLat = String.format(Locale.US, "%.6f", dropoffCoords.first) | ||
| val dropoffLng = String.format(Locale.US, "%.6f", dropoffCoords.second) | ||
| "bolt://ride?pickup_lat=${pickupLat}&pickup_lng=${pickupLng}&destination_lat=${dropoffLat}&destination_lng=${dropoffLng}" | ||
| "https://bolt.eu/ride/?pickup_lat=${pickupCoords.first}&pickup_lng=${pickupCoords.second}&destination_lat=${dropoffCoords.first}&destination_lng=${dropoffCoords.second}" | ||
| } else { | ||
| Log.w("MainViewModel", "Geocoding failed, using fallback Bolt deep link format") | ||
| "bolt://ride?pickup=0&destination=0" | ||
| val pickupEncoded = URLEncoder.encode(pickup, "UTF-8") | ||
| val dropoffEncoded = URLEncoder.encode(dropoff, "UTF-8") | ||
| "bolt://ride?pickup=$pickupEncoded&destination=$dropoffEncoded" | ||
| } | ||
| } |
There was a problem hiding this comment.
The new createBoltDeepLinkWeb function lacks test coverage. Since the repository has comprehensive test coverage for similar functions like createBoltDeepLink (see BoltDeepLinkFormatTest.kt and BoltDeepLinkTest.kt), tests should be added to verify the web deep link format, URL scheme (https://), and parameter encoding.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
| return "uber://?action=setPickup&pickup[formatted_address]=$pickupEncoded&dropoff[formatted_address]=$dropoffEncoded" | ||
| } | ||
|
|
||
| // This deeplink opens the app, but won't work to set destination... |
There was a problem hiding this comment.
The comment states "This deeplink opens the app, but won't work to set destination..." which is misleading. According to the changes, the bolt:// scheme is now being used specifically to open the app, and the function creates a valid deep link with coordinates or fallback parameters. The comment should clarify that this opens the app but the destination setting requires the subsequent HTTPS link.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
|
@neteinstein I've opened a new pull request, #64, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@neteinstein I've opened a new pull request, #65, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@neteinstein I've opened a new pull request, #66, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@neteinstein I've opened a new pull request, #67, to work on those changes. Once the pull request is ready, I'll request review from you. |
* Initial plan * Fix log tag formatting: remove trailing comma and space Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com>
* Initial plan * Fix log tag formatting - remove trailing comma and space Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com> Co-authored-by: Pedro Vicente <pedro.vicente@mindera.com>
…#66) * Initial plan * Add 6 decimal place precision formatting to Bolt deep link coordinates Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com> * Extract coordinate formatting logic into helper function Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com>
* Initial plan * Restore 6 decimal place precision formatting for Bolt deep link coordinates Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com> * Fix createBoltDeepLinkWeb fallback to use web URL scheme Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com> Co-authored-by: Pedro Vicente <pedro.vicente@mindera.com>
|
@copilot Fix:
Fix the issues identified by lint, or create a baseline to see only new errors. For more details, see https://developer.android.com/studio/write/lint#snapshot Lint found 7 errors, 13 warnings. First failure: /home/runner/work/CompareUberVsBoltPriceApp/CompareUberVsBoltPriceApp/app/src/main/java/org/neteinstein/compareapp/data/repository/LocationRepositoryImpl.kt:50: Error: Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with checkPermission) or explicitly handle a potential SecurityException [MissingPermission] The full lint text report is located at:
|
|
@neteinstein I've opened a new pull request, #68, to work on those changes. Once the pull request is ready, I'll request review from you. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Initial plan * Fix MissingPermission lint error in LocationRepositoryImpl Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: neteinstein <910242+neteinstein@users.noreply.github.com> Co-authored-by: Pedro Vicente <pedro.vicente@mindera.com>
|
@neteinstein I've opened a new pull request, #69, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@neteinstein I've opened a new pull request, #70, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@neteinstein I've opened a new pull request, #71, to work on those changes. Once the pull request is ready, I'll request review from you. |
The only reliable solution on Android -> Use dual-intent fallback logic
Try Bolt’s custom scheme → opens app
If it opens, immediately pass control to Bolt’s backend via HTTPS
✅ Working production-safe approach
fun openBolt(context: Context, deepLink: String) {
val boltAppIntent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse("bolt://ride")
setPackage("ee.mtakso.client")
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
}
Why this works
bolt://ride is handled by Bolt ✔️
HTTPS deep link is picked up by the already-running app
Android won’t throw ActivityNotFoundException
This is the same pattern used by several ride-hailing SDKs
✅ Your deep link must be HTTPS
https://bolt.eu/ride/?pickup_lat=...&pickup_lng=...&destination_lat=...&destination_lng=...
This relies on Bolt’s internal intent interception
The delay (300ms) may need tuning (200–500ms)
Works reliably on:
Android 11+
Stock Pixel, Samsung, Xiaomi
Not guaranteed on heavily restricted OEM ROMs