Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,29 @@
package com.google.android.react.navsdk;

import android.content.Context;
import android.util.DisplayMetrics;
import com.google.android.libraries.navigation.NavigationUpdatesOptions;
import com.google.android.libraries.navigation.NavigationUpdatesOptions.GeneratedStepImagesType;
import com.google.android.libraries.navigation.Navigator;

/** Starts and stops the forwarding of turn-by-turn nav info from Nav SDK. */
public class NavForwardingManager {
/** Registers a service to receive navigation updates from nav info */
public static void startNavForwarding(
Navigator navigator, Context context, INavigationCallback navigationCallback) {

DisplayMetrics metrics = context.getResources().getDisplayMetrics();

NavigationUpdatesOptions options =
NavigationUpdatesOptions.builder()
.setNumNextStepsToPreview(Integer.MAX_VALUE)
.setGeneratedStepImagesType(GeneratedStepImagesType.BITMAP)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don’t handle GeneratedStepImagesType yet, so we could default to GeneratedStepImagesType.NONE That said, I’m leaning toward BITMAP, since it already lets developers use the generated bitmaps for Android Auto if needed.

@illuminati1911 any thoughts?

Copy link
Contributor

@illuminati1911 illuminati1911 Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. Agreed on this. Later we can add similar logic as in the Flutter SDK.

As for the PR, looks pretty good to me as well. Please handle the formatting issues.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, let's keep GeneratedStepImagesType.BITMAP for this.

.setDisplayMetrics(metrics)
.build();

boolean success =
navigator.registerServiceForNavUpdates(
context.getPackageName(),
NavInfoReceivingService.class.getName(),
/* numNextStepsToPreview= */ Integer.MAX_VALUE); // Send all remaining steps.
context.getPackageName(), NavInfoReceivingService.class.getName(), options);
if (success) {
navigationCallback.logDebugInfo("Successfully registered service for nav updates");
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.libraries.mapsplatform.turnbyturn.model.Lane;
import com.google.android.libraries.mapsplatform.turnbyturn.model.LaneDirection;
import com.google.android.libraries.mapsplatform.turnbyturn.model.StepInfo;
import com.google.android.libraries.navigation.AlternateRoutesStrategy;
import com.google.android.libraries.navigation.DisplayOptions;
Expand Down Expand Up @@ -103,6 +105,32 @@ public static WritableMap getMapFromStepInfo(StepInfo stepInfo) {
map.putString("exitNumber", stepInfo.getExitNumber());
map.putString("fullRoadName", stepInfo.getFullRoadName());
map.putString("instruction", stepInfo.getFullInstructionText());

List<Lane> lanes = stepInfo.getLanes();
if (lanes != null) {
WritableArray lanesArr = Arguments.createArray();

for (Lane lane : lanes) {
WritableArray dirArr = Arguments.createArray();

List<LaneDirection> dirs = lane.laneDirections();
if (dirs != null) {
for (LaneDirection dir : dirs) {
WritableMap dirMap = Arguments.createMap();
dirMap.putInt("laneShape", dir.laneShape());
dirMap.putBoolean("recommended", dir.isRecommended());
dirArr.pushMap(dirMap);
}
}

WritableMap laneMap = Arguments.createMap();
laneMap.putArray("laneDirections", dirArr);
lanesArr.pushMap(laneMap);
}

map.putArray("lanes", lanesArr);
}

return map;
}

Expand Down
62 changes: 22 additions & 40 deletions ios/react-native-navigation-sdk/NavAutoModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,8 @@ + (void)unregisterNavAutoModuleReadyCallback {
});
}

RCT_EXPORT_METHOD(addMarker
: (NSDictionary *)markerOptions resolver
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(addMarker : (NSDictionary *)markerOptions resolver : (RCTPromiseResolveBlock)
resolve rejecter : (RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_viewController) {
[self->_viewController addMarker:markerOptions
Expand All @@ -134,10 +132,8 @@ + (void)unregisterNavAutoModuleReadyCallback {
});
}

RCT_EXPORT_METHOD(addCircle
: (NSDictionary *)circleOptions resolver
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(addCircle : (NSDictionary *)circleOptions resolver : (RCTPromiseResolveBlock)
resolve rejecter : (RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_viewController) {
[self->_viewController addCircle:circleOptions
Expand All @@ -150,10 +146,8 @@ + (void)unregisterNavAutoModuleReadyCallback {
});
}

RCT_EXPORT_METHOD(addPolyline
: (NSDictionary *)polylineOptions resolver
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(addPolyline : (NSDictionary *)polylineOptions resolver : (RCTPromiseResolveBlock)
resolve rejecter : (RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_viewController) {
[self->_viewController addPolyline:polylineOptions
Expand All @@ -166,10 +160,8 @@ + (void)unregisterNavAutoModuleReadyCallback {
});
}

RCT_EXPORT_METHOD(addPolygon
: (NSDictionary *)polygonOptions resolver
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(addPolygon : (NSDictionary *)polygonOptions resolver : (RCTPromiseResolveBlock)
resolve rejecter : (RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_viewController) {
[self->_viewController addPolygon:polygonOptions
Expand Down Expand Up @@ -278,10 +270,8 @@ + (void)unregisterNavAutoModuleReadyCallback {
});
}

RCT_EXPORT_METHOD(setZoomLevel
: (nonnull NSNumber *)level resolver
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(setZoomLevel : (nonnull NSNumber *)level resolver : (RCTPromiseResolveBlock)
resolve rejecter : (RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_viewController) {
[self->_viewController setZoomLevel:level];
Expand Down Expand Up @@ -315,9 +305,8 @@ + (void)unregisterNavAutoModuleReadyCallback {
});
}

RCT_EXPORT_METHOD(getCameraPosition
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(getCameraPosition : (RCTPromiseResolveBlock)
resolve rejecter : (RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_viewController) {
[self->_viewController getCameraPosition:^(NSDictionary *result) {
Expand All @@ -329,9 +318,8 @@ + (void)unregisterNavAutoModuleReadyCallback {
});
}

RCT_EXPORT_METHOD(getMyLocation
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(getMyLocation : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)
reject) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_viewController) {
[self->_viewController getMyLocation:^(NSDictionary *_Nullable result) {
Expand All @@ -343,9 +331,8 @@ + (void)unregisterNavAutoModuleReadyCallback {
});
}

RCT_EXPORT_METHOD(getUiSettings
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(getUiSettings : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)
reject) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_viewController) {
[self->_viewController getUiSettings:^(NSDictionary *_Nullable result) {
Expand All @@ -357,9 +344,8 @@ + (void)unregisterNavAutoModuleReadyCallback {
});
}

RCT_EXPORT_METHOD(isMyLocationEnabled
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(isMyLocationEnabled : (RCTPromiseResolveBlock)
resolve rejecter : (RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_viewController) {
[self->_viewController isMyLocationEnabled:^(BOOL result) {
Expand All @@ -379,20 +365,16 @@ + (void)unregisterNavAutoModuleReadyCallback {
});
}

RCT_EXPORT_METHOD(isAutoScreenAvailable
: (RCTPromiseResolveBlock)resolve rejecter
: (RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(isAutoScreenAvailable : (RCTPromiseResolveBlock)
resolve rejecter : (RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
BOOL hasViewController = self->_viewController != nil;
resolve([NSNumber numberWithBool:hasViewController]);
});
}

RCT_EXPORT_METHOD(setPadding
: (nonnull NSNumber *)top left
: (nonnull NSNumber *)left bottom
: (nonnull NSNumber *)bottom right
: (nonnull NSNumber *)right) {
RCT_EXPORT_METHOD(setPadding : (nonnull NSNumber *)top left : (nonnull NSNumber *)
left bottom : (nonnull NSNumber *)bottom right : (nonnull NSNumber *)right) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_viewController) {
[self->_viewController setPadding:UIEdgeInsetsMake(top.floatValue, left.floatValue,
Expand Down
Loading
Loading