-
Notifications
You must be signed in to change notification settings - Fork 3
Module Navigation
Specialized module for simple implementation of Navigation functionality including Signpost View (Full, Simplified), Simple Lanes View, Infobar, Route Preview Controls, Current Speed View, Speed Limit View and Action Menu. Every feature is customizable by end developer (can be turned on/off or styled).
Before you start, please use README to learn how to integrate this module into your project.
NOTE: This module uses custom global theme attributes. Please define them first or use/extend our predefined theme! (otherwise, the app will crash :( )
The most basic example. It shows the Navigation module with zero lines of configuration. It also contains basic location access and permission logic. This sample use your current location as start position, so you can try the real navigation with it.
Xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/navigationFragment"
class="com.sygic.maps.module.navigation.NavigationFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Activity
class NavigationDefaultActivity : CommonSampleActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navigation_default)
if (savedInstanceState == null) {
createRoutePlanAndComputeRoute()
}
}
private fun createRoutePlanAndComputeRoute() {
requestLastValidLocation { lastValidLocation ->
val routePlan = RoutePlan().apply {
setStart(lastValidLocation)
setDestination(GeoCoordinates(41.893056, 12.482778))
routingOptions = RoutingOptions().apply {
transportMode = RoutingOptions.TransportMode.Car
routingType = RoutingOptions.RoutingType.Economic
}
}
computePrimaryRoute(routePlan) { route ->
(supportFragmentManager.findFragmentById(R.id.navigationFragment) as NavigationFragment).routeInfo =
route
}
}
}
private fun requestLastValidLocation(currentLocationCallback: (GeoCoordinates) -> Unit) {
if (isPermissionNotGranted(Manifest.permission.ACCESS_FINE_LOCATION)) {
requestPermission(Manifest.permission.ACCESS_FINE_LOCATION, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION)
return
}
if (isGpsNotEnabled()) {
if (isGooglePlayServicesAvailable()) {
createGoogleApiLocationRequest(REQUEST_CODE_GOOGLE_API_CLIENT)
} else {
showGenericNoGpsDialog(REQUEST_CODE_SETTING_ACTIVITY)
}
return
}
getLastValidLocation(currentLocationCallback)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
createRoutePlanAndComputeRoute()
} else {
longToast("Sorry, location permission is needed!")
finish()
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_CODE_SETTING_ACTIVITY, REQUEST_CODE_GOOGLE_API_CLIENT -> {
if (isGpsEnabled()) {
createRoutePlanAndComputeRoute()
} else {
longToast("GPS module is not enabled :(")
finish()
}
}
}
}
}
The most basic example with navigation preview mode enabled (the route demonstration is automatically started from the specific start position).
Xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/navigationFragment"
class="com.sygic.maps.module.navigation.NavigationFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sygic_navigation_previewMode="true" />
</FrameLayout>
Activity
class NavigationPreviewEnabledActivity : CommonSampleActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navigation_preview_enabled)
if (savedInstanceState == null) {
computePrimaryRoute(SampleDemonstrationRoutePlan()) { route ->
(supportFragmentManager.findFragmentById(R.id.navigationFragment) as NavigationFragment).routeInfo = route
}
}
}
}
The navigation example with sygic_signpost_type set to simplified and navigation preview mode enabled.
Xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/navigationFragment"
class="com.sygic.maps.module.navigation.NavigationFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sygic_navigation_previewMode="true"
app:sygic_signpost_type="simplified" />
</FrameLayout>
Activity
class NavigationSimplifiedSignpostActivity : CommonSampleActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navigation_simplified_signpost)
if (savedInstanceState == null) {
computePrimaryRoute(SampleDemonstrationRoutePlan()) { route ->
(supportFragmentManager.findFragmentById(R.id.navigationFragment) as NavigationFragment).routeInfo = route
}
}
}
}
The navigation example with custom infobar click listener without braking the default lock functionality.
Xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/navigationFragment"
class="com.sygic.maps.module.navigation.NavigationFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:sygic_navigation_previewMode="true" />
</FrameLayout>
Activity
class NavigationInfobarCustomClickListenerActivity : CommonSampleActivity() {
private var fanfareMediaPlayer: MediaPlayer? = null
private lateinit var navigationFragment: NavigationFragment
private val unlockedLeftInfobarButtonClickListener = object : OnInfobarButtonClickListener {
override val button = NavigationDefaultUnlockedLeftInfobarButton()
override fun onButtonClick() = lockVehicle()
}
private val customLeftInfobarButtonClickListener = object : OnInfobarButtonClickListener {
override val button = InfobarButton(
R.drawable.ic_play,
R.drawable.bg_infobar_button_rounded,
R.color.white,
R.color.colorAccent
)
override fun onButtonClick() = playFanfare()
}
private val cameraModeChangedListener = object : Camera.ModeChangedListener {
override fun onRotationModeChanged(@Camera.RotationMode mode: Int) {}
override fun onMovementModeChanged(@Camera.MovementMode mode: Int) {
when (mode) {
Camera.MovementMode.Free ->
setLeftInfobarButtonClickListener(unlockedLeftInfobarButtonClickListener)
Camera.MovementMode.FollowGpsPosition, Camera.MovementMode.FollowGpsPositionWithAutozoom ->
setLeftInfobarButtonClickListener(customLeftInfobarButtonClickListener)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_navigation_infobar_custom_click_listener)
fanfareMediaPlayer = MediaPlayer.create(this, R.raw.fanfare)
navigationFragment = (supportFragmentManager.findFragmentById(R.id.navigationFragment) as NavigationFragment)
if (savedInstanceState == null) {
setLeftInfobarButtonClickListener(customLeftInfobarButtonClickListener)
computePrimaryRoute(SampleDemonstrationRoutePlan()) {
navigationFragment.routeInfo = it
}
}
}
override fun onResume() {
super.onResume()
navigationFragment.cameraDataModel.addModeChangedListener(cameraModeChangedListener)
}
private fun setLeftInfobarButtonClickListener(listener: OnInfobarButtonClickListener) =
navigationFragment.setOnInfobarButtonClickListener(InfobarButtonType.LEFT, listener)
private fun playFanfare() {
fanfareMediaPlayer?.apply {
if (isPlaying) {
stop()
prepare()
}
start()
}
}
private fun lockVehicle() {
with(supportFragmentManager.findFragmentById(R.id.navigationFragment)) {
if (this is NavigationFragment) {
cameraDataModel.rotationMode = Camera.RotationMode.Vehicle
cameraDataModel.movementMode = Camera.MovementMode.FollowGpsPositionWithAutozoom
}
}
}
override fun onPause() {
super.onPause()
((supportFragmentManager.findFragmentById(R.id.navigationFragment) as NavigationFragment))
.cameraDataModel.removeModeChangedListener(cameraModeChangedListener)
}
override fun onDestroy() {
super.onDestroy()
fanfareMediaPlayer?.apply {
stop()
if (isFinishing) release()
}
}
}