Skip to content

Commit 06e98f7

Browse files
feat: add isPromptVisible to android auto base screen
1 parent 793d8fd commit 06e98f7

2 files changed

Lines changed: 66 additions & 2 deletions

File tree

ANDROIDAUTO.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,32 @@ public Template onGetTemplate() {
6161
}
6262
```
6363

64+
### Avoiding overlap with Navigation SDK prompts
65+
66+
`AndroidAutoBaseScreen` detects Navigation SDK prompts, including traffic and rerouting prompts,
67+
and automatically invalidates the Android Auto template when their visibility changes. If your
68+
custom `NavigationTemplate` includes a `TravelEstimate`, conditionally omit it while a prompt is
69+
visible. This prevents the host-controlled estimate from overlapping the Navigation SDK modal
70+
prompt:
71+
72+
```java
73+
@Override
74+
public Template onGetTemplate() {
75+
NavigationTemplate.Builder builder = new NavigationTemplate.Builder();
76+
// Configure actions, map action strip, and navigation info.
77+
78+
if (!isPromptVisible()) {
79+
builder.setDestinationTravelEstimate(travelEstimate);
80+
}
81+
82+
return builder.build();
83+
}
84+
```
85+
86+
`isPromptVisible()` is provided by `AndroidAutoBaseScreen`; subclasses do not need to register a
87+
listener or call `invalidate()` themselves. The estimate is restored automatically when the prompt
88+
disappears.
89+
6490
For advanced customization, you can bypass the base class and implement your own screen by inheriting `Screen`. You can use the provided `AndroidAutoBaseScreen` base class as a reference on how to do that.
6591

6692
### React Native specific setup

android/src/main/java/com/google/android/react/navsdk/AndroidAutoBaseScreen.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import com.google.android.gms.maps.GoogleMap;
4444
import com.google.android.gms.maps.GoogleMapOptions;
4545
import com.google.android.libraries.navigation.NavigationView;
46+
import com.google.android.libraries.navigation.PromptVisibilityChangedListener;
4647
import com.google.android.libraries.navigation.StylingOptions;
4748
import org.json.JSONObject;
4849

@@ -64,7 +65,9 @@ public abstract class AndroidAutoBaseScreen extends Screen
6465
protected GoogleMap mGoogleMap;
6566
protected volatile boolean mNavigationInitialized = false;
6667
private MapViewController mMapViewController;
68+
private PromptVisibilityChangedListener mPromptVisibilityChangedListener;
6769
private boolean mIsSurfaceDestroyed = true;
70+
private boolean mIsPromptVisible = false;
6871

6972
private boolean mAndroidAutoModuleInitialized = false;
7073
private boolean mNavModuleInitialized = false;
@@ -95,6 +98,31 @@ private void updateNavigationUiEnabled(boolean ready) {
9598
});
9699
}
97100

101+
private void handlePromptVisibilityChanged(
102+
NavigationView navigationView, boolean promptVisible) {
103+
UiThreadUtil.runOnUiThread(
104+
() -> {
105+
if (mIsSurfaceDestroyed
106+
|| navigationView != mNavigationView
107+
|| mIsPromptVisible == promptVisible) {
108+
return;
109+
}
110+
111+
mIsPromptVisible = promptVisible;
112+
onPromptVisibilityChanged(promptVisible);
113+
});
114+
}
115+
116+
/** Returns whether a Navigation SDK prompt is visible over the Android Auto map. */
117+
protected final boolean isPromptVisible() {
118+
return mIsPromptVisible;
119+
}
120+
121+
/** Called when Navigation SDK prompt visibility changes on the Android Auto map. */
122+
protected void onPromptVisibilityChanged(boolean promptVisible) {
123+
invalidate();
124+
}
125+
98126
/**
99127
* Called when the navigation session state changes. Override this method in your subclass to
100128
* handle navigation ready state changes.
@@ -211,10 +239,14 @@ public void onSurfaceAvailable(@NonNull SurfaceContainer surfaceContainer) {
211239
mNavigationView.setReportIncidentButtonEnabled(false);
212240
mNavigationView.setNavigationUiEnabled(mNavigationInitialized);
213241

214-
mPresentation.setContentView(mNavigationView);
242+
NavigationView navigationView = mNavigationView;
243+
mPromptVisibilityChangedListener =
244+
promptVisible -> handlePromptVisibilityChanged(navigationView, promptVisible);
245+
navigationView.addPromptVisibilityChangedListener(mPromptVisibilityChangedListener);
246+
247+
mPresentation.setContentView(navigationView);
215248
mPresentation.show();
216249

217-
NavigationView navigationView = mNavigationView;
218250
navigationView.getMapAsync(
219251
(GoogleMap googleMap) -> {
220252
if (mIsSurfaceDestroyed || navigationView != mNavigationView) {
@@ -249,12 +281,18 @@ public void onSurfaceDestroyed(@NonNull SurfaceContainer surfaceContainer) {
249281
unRegisterControllersForAndroidAutoModule();
250282
mMapViewController = null;
251283

284+
if (mNavigationView != null && mPromptVisibilityChangedListener != null) {
285+
mNavigationView.removePromptVisibilityChangedListener(mPromptVisibilityChangedListener);
286+
}
287+
mPromptVisibilityChangedListener = null;
288+
252289
if (mNavigationView != null) {
253290
mNavigationView.onPause();
254291
mNavigationView.onStop();
255292
mNavigationView.onDestroy();
256293
mNavigationView = null;
257294
}
295+
mIsPromptVisible = false;
258296
mGoogleMap = null;
259297

260298
if (mPresentation != null) {

0 commit comments

Comments
 (0)