Integrating Real-Time Traffic Updates with the HERE SDK Navigate
Sachin Jonda — 12 December 2024
1 min read
29 June 2023
Last week, we showed you how to render real-time realistic views during navigation using HERE SDK Navigate Edition. This week, we have another exciting tutorial for you: how to listen to the device hardware motion sensors like gyroscope or magnetometer to update the azimuth value on the device motion and orientation in HERE SDK. This will allow you to implement custom compass functionality with HERE SDK for Android (Navigate edition), and enhance your app's navigation capabilities. Let’s get started!
Implementing the compass functionality while Navigation
1. Create UI Part in XML file for Navigation Screen
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent”>
———— Other UI Components ————
<androidx.cardview.widget.CardView android:layout_width="50dp" android:layout_height="50dp" android:clickable="true" android:onClick="compassClicked" app:cardCornerRadius="25dp" app:cardPreventCornerOverlap="true" app:cardUseCompatPadding="false" app:contentPadding="6dp">
<ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/compass_needle" /> </androidx.cardview.widget.CardView></RelativeLayout>
2. Create a variable in class file for checking the compass status, name it as “isCompassOn”
private boolean isCompassOn = true;
3. Create a function in the class for compassClicked
public void compassClicked(View view) { isCompassOn = !isCompassOn;}
4. Define a sensor manager for compass sensor
//For compass UIprivate CardView compassFab;//For sensor configsprivate SensorManager mSensorManager;private Sensor mRotationSensor;private float[] mRotationMatrix = new float[9];private float[] mOrientation = new float[3];//For current locationprivate GeoCoordinates currentLocation; //Additional variable for saving map camera zoomprivate int cameraZoom = 0;
5. Initialize the variables in onCreate function
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_navigation);compassFab = findViewById(R.id.compassFab);//sensor configsmSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);// Get a reference to the rotation vector sensormRotationSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);}
6. Register map camera listener with map; and register and unregister sensor listener in onResume and onStop respectively.
public class NavigationActivity extends AppCompatActivity implements SensorEventListener, MapCameraListener {
mapView.getMapScene().loadScene(MapScheme.NORMAL_DAY, new MapScene.LoadSceneCallback() { @Override public void onLoadScene(@Nullable MapError mapError) { if (mapError == null) { ——— other functions ————— mapView.getCamera().addListener(NavigationActivity.this); } else { Log.d(TAG, "Loading map failed: mapErrorCode: " + mapError.name()); } } }
@Override protected void onResume() { super.onResume(); // Register the sensor listener mSensorManager.registerListener(this, mRotationSensor, SensorManager.SENSOR_DELAY_NORMAL); }
@Override protected void onPause() { super.onPause(); // Unregister the sensor listener mSensorManager.unregisterListener(this); }}
7. Save the current location from the navigation location listener on visual navigator
visualNavigator.setNavigableLocationListener(new NavigableLocationListener() { @Override public void onNavigableLocationUpdated(@NonNull NavigableLocation currentNavigableLocation) { ———— other functionality ————— currentLocation = currentNavigableLocation.originalLocation.coordinates; } });
8. Change the compass icon rotation according to the map camera rotation if compass is ON
@Override public void onMapCameraUpdated(@NonNull MapCamera.State state) { // Rotate the compass image if (isCompassOn) { compassFab.setRotation((float) state.orientationAtTarget.bearing); } }
9. Change the map camera according to the sensor
@Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { // Convert the rotation vector to a rotation matrix SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values); // Convert the rotation matrix to orientation angles SensorManager.getOrientation(mRotationMatrix, mOrientation); // Convert the azimuth angle to degrees float azimuthInRadians = mOrientation[0]; float azimuthInDegrees = (float) Math.toDegrees(azimuthInRadians);
// Rotate the map camera and compass image using compass sensor if (!isCompassOn) { compassFab.setRotation(-azimuthInDegrees); GeoOrientationUpdate orientationUpdate = new GeoOrientationUpdate((double) -azimuthInDegrees, 0.0); if (currentLocation != null) { // please make a check for zoom as it should be one time only mapView.getCamera().startAnimation(MapCameraAnimationFactory.flyTo(new GeoCoordinatesUpdate(currentLocation), orientationUpdate, cameraZoom == 0 ? 300 : 0, Duration.ofMillis(1))); cameraZoom = 300; } } } }
@Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // Do nothing }
Conclusion
We hope this tutorial has shown you how to use device hardware motion sensors with HERE SDK to create custom compass functionality for your navigation apps. This feature can enhance the user experience by providing more accurate and reliable orientation information. You can also customize the appearance and behavior of the compass to suit your app design and preferences. HERE SDK offers many other features and capabilities for creating amazing navigation apps, so make sure to check out our developer blog for more tips and tricks. If you have any questions or comments, reach us out on our Slack channel, and we'll be happy to assist you! Or simply drop by to say hi and connect with fellow developers. We're looking forward to hearing from you!
Resources
Full-fledged Android reference application source code including above implementation can be downloaded from - https://demo.support.here.com/sdk_examples/HEREDriveAndroid.zip
For more examples, please visit - https://demo.support.here.com/mobilesdk_examples
Sachin Jonda
Principal Support Engineer
Share article
Sachin Jonda — 12 December 2024
Sachin Jonda — 25 November 2024
Aaron Falk — 21 October 2024
Why sign up:
Latest offers and discounts
Tailored content delivered weekly
Exclusive events
One click to unsubscribe