eopeter / flutter_mapbox_navigation

Turn By Turn Navigation for Your Flutter Application
Apache License 2.0
217 stars 185 forks source link

VoiceInstructionsEnabled has an issue. #359

Open tig-bbit opened 6 months ago

tig-bbit commented 6 months ago

I am using the latest verstion of the plugin (0.2.2) also. And if I set voiceInstructionsEnabled: false, the app is shut down unexpectly. But the app runs flexible if voiceInstructionsEnable: true. So I cannot customize voiceInstruction. How can I resolve this?

E/AndroidRuntime(27278): FATAL EXCEPTION: main E/AndroidRuntime(27278): Process: com.example.untitled, PID: 27278 E/AndroidRuntime(27278): java.net.MalformedURLException: no protocol: /directions/v5/mapbox/driving/-6.58909461927%2C53.3826809636;-6.587864%2C53.388655;-6.589743%2C53.387647;-6.599891%2C53.389552;-6.599701%2C53.389442;-6.59922%2C53.390455;-6.590373%2C53.382565?access_token=pk***&alternatives=true&avoid_maneuver_radius=18.031&bearings=151.365%2C45%3B%3B%3B%3B%3B%3B&continue_straight=true&enable_refresh=true&geometries=polyline6&layers=0%3B%3B%3B%3B%3B%3B&routes_history=KPXGmPFtKwnbI6HMo6FRbRxdivKvP0ZHiDyopIeIl77o0tgPRT9r1A%3D%3D_us-west-2%2C0%2C0&steps=true&waypoint_names=%3BLyreen%20Lawn%3BLyreen%20Drive%3BMoyglare%20Village%3BMoyglare%20Village%3BMoyglare%20Abbey%3BCross%20Lane&waypoints=0%3B1%3B2%3B3%3B4%3B5%3B6 E/AndroidRuntime(27278): at java.net.URL.(URL.java:601) E/AndroidRuntime(27278): at java.net.URL.(URL.java:498) E/AndroidRuntime(27278): at java.net.URL.(URL.java:447) E/AndroidRuntime(27278): at com.mapbox.navigation.base.route.NavigationRouteEx.toNavigationRoute(NavigationRoute.kt:588) E/AndroidRuntime(27278): at com.mapbox.navigation.base.internal.route.NavigationRouteEx.toNavigationRoute(NavigationRouteEx.kt:244) E/AndroidRuntime(27278): at com.mapbox.navigation.base.internal.utils.DirectionsResponseUtilsKt.parseRouteInterface(DirectionsResponseUtils.kt:59) E/AndroidRuntime(27278): at com.mapbox.navigation.base.internal.utils.DirectionsResponseUtilsKt.parseNativeDirectionsAlternative(DirectionsResponseUtils.kt:51) E/AndroidRuntime(27278): at com.mapbox.navigation.core.routealternatives.RouteAlternativesController$processRouteAlternatives$1$alternatives$1$expected$1.invokeSuspend(RouteAlternativesController.kt:219) E/AndroidRuntime(27278): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) E/AndroidRuntime(27278): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) E/AndroidRuntime(27278): at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570) E/AndroidRuntime(27278): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750) E/AndroidRuntime(27278): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677) E/AndroidRuntime(27278): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664) E/AndroidRuntime(27278): Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@eec93ae, Dispatchers.Main] I/Process (27278): Sending signal. PID: 27278 SIG: 9 Lost connection to device.

fc0101 commented 6 months ago

I think, It comes from wrong configration setting.

Android Configuration

  1. Mapbox APIs and vector tiles require a Mapbox account and API access token. Add a new resource file called mapbox_access_token.xml with it's full path being <YOUR_FLUTTER_APP_ROOT>/android/app/src/main/res/values/mapbox_access_token.xml . Then add a string resource with name "mapbox_access_token" and your token as it's value as shown below. You can obtain an access token from the Mapbox account page.

``

ADD_MAPBOX_ACCESS_TOKEN_HERE

``

  1. Add the following permissions to the app level Android Manifest `` ...

    ... ``

  2. Add the MapBox Downloads token with the downloads:read scope to your gradle.properties file in Android folder to enable downloading the MapBox binaries from the repository. To secure this token from getting checked into source control, you can add it to the gradle.properties of your GRADLE_HOME which is usually at $USER_HOME/.gradle for Mac. This token can be retrieved from your MapBox Dashboard. You can review the Token Guide to learn more about download tokens

MAPBOX_DOWNLOADS_TOKEN=sk.XXXXXXXXXXXXXXX

After adding the above, your gradle.properties file may look something like this:

org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true MAPBOX_DOWNLOADS_TOKEN=sk.epe9nE9peAcmwNzKVNqSbFfp2794YtnNepe9nE9peAcmwNzKVNqSbFfp2794YtnN.-HrbMMQmLdHwYb8r

  1. Update MainActivity.kt to extends FlutterFragmentActivity vs FlutterActivity. Otherwise you'll get Caused by: java.lang.IllegalStateException: Please ensure that the hosting Context is a valid ViewModelStoreOwner. ``import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity: FlutterFragmentActivity() { }` Add implementation platform("org.jetbrains.kotlin:kotlin-bom:1.8.0")toandroid/app/build.gradle`

tig-bbit commented 6 months ago

Thanks for reaching out. @fc0101 But As I said before, the app is normal when the voiceInstructionEnabled: true. So I don't think is issue comes from wrong configuration setting. I set all configuration correctly. But if I set the voiceInctructionEnabled: false in multi Waypoints mode, when I get second waypoint, the app is crashed and outputs the error.

tig-bbit commented 6 months ago

the main error is following: java.net.MalformedURLException: no protocol: /directions/v5/mapbox/driving/-6.58909461927%2C53.3826809636;-6.587864%2C53.388655;-6.589743%2C53.387647;-6.599891%2C53.389552;-6.599701%2C53.389442;-6.59922%2C53.390455;-6.590373%2C53.382565?access_token=pk***&alternatives=true&avoid_maneuver_radius=18.031&bearings=151.365%2C45%3B%3B%3B%3B%3B%3B&continue_straight=true&enable_refresh=true&geometries=polyline6&layers=0%3B%3B%3B%3B%3B%3B&routes_history=KPXGmPFtKwnbI6HMo6FRbRxdivKvP0ZHiDyopIeIl77o0tgPRT9r1A%3D%3D_us-west-2%2C0%2C0&steps=true&waypoint_names=%3BLyreen%20Lawn%3BLyreen%20Drive%3BMoyglare%20Village%3BMoyglare%20Village%3BMoyglare%20Abbey%3BCross%20Lane&waypoints=0%3B1%3B2%3B3%3B4%3B5%3B6

jaylee137 commented 6 months ago

The java.net.MalformedURLException: no protocol error indicates that the URL generated for the directions request is missing the protocol part (e.g., http:// or https://). This can happen if the URL is incorrectly constructed.

Given that this issue arises specifically when voiceInstructionsEnabled is set to false, it's likely that some part of the URL generation logic is conditional on this setting and is not correctly handling the case where voice instructions are disabled.

Steps to Diagnose and Fix the Issue

  1. Inspect the URL Generation Logic: Review the part of your code where the URL for the directions request is generated. Look for any conditional logic that depends on voiceInstructionsEnabled.

  2. Ensure Protocol is Included: Make sure that the URL always includes the protocol (e.g., https://) regardless of the voiceInstructionsEnabled setting.

    Example Inspection and Fix

Here's an example of how you might inspect and fix the URL generation logic:

// Assume this is the part of your code where the URL is generated
fun generateDirectionsUrl(params: DirectionsParams): String {
    val baseUrl = "https://api.mapbox.com"
    val endpoint = "/directions/v5/mapbox/driving"

    // Construct the waypoints part of the URL
    val waypoints = params.waypoints.joinToString(";") { "${it.longitude},${it.latitude}" }

    // Construct other query parameters
    val queryParams = "access_token=${params.accessToken}&alternatives=true&steps=true&geometries=polyline6"

    // Combine all parts to form the complete URL
    val url = "$baseUrl$endpoint/$waypoints?$queryParams"

    return url
}

// Example usage
val directionsParams = DirectionsParams(
    accessToken = "pk.************************************",
    waypoints = listOf(
        Waypoint(-6.58909461927, 53.3826809636),
        Waypoint(-6.587864, 53.388655),
        // add other waypoints
    )
)

val directionsUrl = generateDirectionsUrl(directionsParams)

Check for Conditional Logic

Ensure that any conditional logic based on voiceInstructionsEnabled does not alter the protocol or base URL:

val voiceInstructionsEnabled = false // or true

val directionsUrl = if (voiceInstructionsEnabled) {
    generateDirectionsUrlWithVoice(params)
} else {
    generateDirectionsUrlWithoutVoice(params)
}

// Ensure both functions generate complete URLs
fun generateDirectionsUrlWithVoice(params: DirectionsParams): String {
    val baseUrl = "https://api.mapbox.com"
    val endpoint = "/directions/v5/mapbox/driving"
    // construct URL as before
    // ensure the protocol is included
}

fun generateDirectionsUrlWithoutVoice(params: DirectionsParams): String {
    val baseUrl = "https://api.mapbox.com"
    val endpoint = "/directions/v5/mapbox/driving"
    // construct URL as before
    // ensure the protocol is included
}

Add Logging

Add logging to check the URL generated in both cases:

val directionsUrl = if (voiceInstructionsEnabled) {
    generateDirectionsUrlWithVoice(params)
} else {
    generateDirectionsUrlWithoutVoice(params)
}

Log.d("Generated URL", directionsUrl)

The no protocol error indicates that the URL lacks the required http:// or https:// prefix. By reviewing the URL generation logic and ensuring the protocol is always included, you can resolve this issue. Logging the generated URLs will help you verify that the URLs are correctly formed in both cases. If the problem persists after these checks, consider reporting the issue to the Mapbox support team with detailed information.