Skip to content

Troubleshooting

Welcome to the MINE - Indoor Navigation Engine troubleshooting guide. This comprehensive resource helps you diagnose and resolve common issues quickly and efficiently.

Quick Resolution

Most issues can be resolved in minutes using the solutions below. If you need additional help, don't hesitate to contact our support team.


Common Issues

Quick Navigation


Map Loading Issues

Map File Not Found

Error Message

Error: Map file not found at path: maps/venue.json
FileNotFoundException: maps/venue.json (No such file or directory)

Cause: The map file doesn't exist in the specified location or the path is incorrect.

Solutions:

Verify the map file is in the correct directory:

// Make sure the file is in assets folder
// Project structure should look like:
// app/src/main/assets/maps/venue.json

val mapData = JsonUtil.LoadJsonFromAsset(
    context = context,
    fileName = "maps/venue.json" // Path relative to assets folder
)

Ensure the assets folder is properly configured:

// build.gradle
android {
    sourceSets {
        main {
            assets.srcDirs = ['src/main/assets']
        }
    }
}

Verify file name and extension:

// Common mistakes:
// ❌ Wrong: "map.json" (missing folder)
// ❌ Wrong: "/maps/venue.json" (leading slash)
// ✅ Correct: "maps/venue.json"

val mapPath = "maps/venue.json"
val mapData = JsonUtil.LoadJsonFromAsset(context, mapPath)

if (mapData == null) {
    Log.e("Map", "Failed to load map from: $mapPath")
    // Check if file exists
    try {
        context.assets.open(mapPath).use { 
            Log.d("Map", "File exists but failed to parse")
        }
    } catch (e: FileNotFoundException) {
        Log.e("Map", "File does not exist: $mapPath")
    }
}

Verification:

// List all files in assets to verify
fun listAssetFiles(context: Context, path: String = "") {
    try {
        val files = context.assets.list(path) ?: emptyArray()
        files.forEach { file ->
            Log.d("Assets", "Found: $path/$file")
        }
    } catch (e: Exception) {
        Log.e("Assets", "Error listing assets: ${e.message}")
    }
}

Invalid Map JSON Format

Error Message

JsonSyntaxException: Expected BEGIN_OBJECT but was STRING
Error parsing map data

Cause: The JSON file contains syntax errors or invalid structure.

Solutions:

Use an online JSON validator:

  1. Copy your JSON content
  2. Visit jsonlint.com
  3. Paste and validate
  4. Fix any reported errors

Ensure all required fields are present:

{
  "id": "venue-001",
  "name": "My Venue",
  "version": "1.0.0",
  "modelPath": "models/venue.glb",
  "floors": [
    {
      "id": "ground",
      "name": "Ground Floor",
      "level": 0,
      "defaultFloor": true
    }
  ]
}

Implement robust error handling:

fun loadMapSafely(context: Context, fileName: String): MapBuild? {
    return try {
        val mapData = JsonUtil.LoadJsonFromAsset(context, fileName)

        // Validate loaded data
        if (mapData?.floors.isNullOrEmpty()) {
            Log.e("Map", "Map has no floors defined")
            return null
        }

        if (mapData.modelPath.isEmpty()) {
            Log.e("Map", "Map has no model path")
            return null
        }

        mapData
    } catch (e: JsonSyntaxException) {
        Log.e("Map", "JSON syntax error: ${e.message}")
        null
    } catch (e: Exception) {
        Log.e("Map", "Error loading map: ${e.message}")
        null
    }
}

3D Model Not Loading

Symptom

Map JSON loads successfully but the 3D model doesn't appear on screen.

Solutions:

// Verify model file exists
val modelPath = mapData.modelPath // e.g., "models/venue.glb"

try {
    context.assets.open(modelPath).use { stream ->
        val size = stream.available()
        Log.d("Model", "Model file found: $modelPath (${size} bytes)")
    }
} catch (e: FileNotFoundException) {
    Log.e("Model", "Model file not found: $modelPath")
}

Ensure the model is in the correct format:

  • ✅ Supported: .glb, .gltf
  • ❌ Not supported: .obj, .fbx, .blend

Convert your model if needed using Blender or online tools.

// Large models may take time to load
sceneView.setOnModelLoadListener(object : ModelLoadListener {
    override fun onLoadStart() {
        showLoadingIndicator()
    }

    override fun onLoadProgress(progress: Float) {
        updateLoadingProgress(progress)
    }

    override fun onLoadComplete() {
        hideLoadingIndicator()
    }

    override fun onLoadError(error: String) {
        Log.e("Model", "Load error: $error")
        showErrorDialog(error)
    }
})

Symptom

Calling startNavigation() doesn't initiate navigation or shows no error.

Solutions:

// Ensure location permission is granted
if (ContextCompat.checkSelfPermission(
        this,
        Manifest.permission.ACCESS_FINE_LOCATION
    ) != PackageManager.PERMISSION_GRANTED
) {
    // Request permission
    ActivityCompat.requestPermissions(
        this,
        arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
        LOCATION_PERMISSION_REQUEST
    )
    return
}

// Start navigation after permission granted
navigationManager.startNavigation(destination)
// Check if route was calculated successfully
val route = pathFinder.findPath(start, destination)

if (route == null) {
    Log.e("Navigation", "Failed to calculate route")
    showError("Cannot find route to destination")
    return
}

if (route.waypoints.isEmpty()) {
    Log.e("Navigation", "Route has no waypoints")
    return
}

// Start navigation with valid route
navigationManager.startNavigation(destination, route)
// Ensure all components are initialized
class NavigationActivity : AppCompatActivity() {

    private lateinit var sceneView: MineSceneView
    private lateinit var navigationManager: UserNavigationManager
    private lateinit var locationTracker: LocationTracker

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Initialize in correct order
        sceneView = MineSceneView(this)
        setContentView(sceneView)

        // Load map first
        loadMap()

        // Initialize location tracking
        locationTracker = LocationTracker(this)
        locationTracker.startTracking()

        // Initialize navigation last
        navigationManager = UserNavigationManager(this, sceneView)
    }
}

Beacons Not Detected

Symptom

Location tracking shows low accuracy or no position updates.

Solutions:

// Verify Bluetooth is enabled
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()

if (bluetoothAdapter == null) {
    showError("Device doesn't support Bluetooth")
    return
}

if (!bluetoothAdapter.isEnabled) {
    // Request to enable Bluetooth
    val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
}
{
  "beacons": [
    {
      "id": "beacon-001",
      "uuid": "f7826da6-4fa2-4e98-8024-bc5b71e0893e",
      "major": 1,
      "minor": 1,
      "location": {
        "x": 10.0,
        "y": 5.0,
        "z": 0.0
      },
      "floor": "ground"
    }
  ]
}
locationTracker.setBeaconConfig(BeaconConfig(
    scanInterval = 1000,
    rangingEnabled = true,
    minRSSI = -90, // Increase range
    supportedTypes = listOf(
        BeaconType.IBEACON,
        BeaconType.EDDYSTONE
    )
))

// Monitor beacon detection
locationTracker.setBeaconListener { beacons ->
    Log.d("Beacons", "Detected ${beacons.size} beacons")
    beacons.forEach { beacon ->
        Log.d("Beacon", "ID: ${beacon.id}, RSSI: ${beacon.rssi}")
    }
}

Verify beacons are working:

  1. Use a beacon scanner app (e.g., "Beacon Scanner" on Play Store)
  2. Check if beacons appear in the scanner
  3. Verify UUID, major, and minor values match your configuration
  4. Check battery level of beacons
  5. Ensure beacons have clear line of sight

Incorrect Navigation Instructions

Symptom

Turn-by-turn instructions appear at wrong locations or with incorrect directions.

Solutions:

// Ensure accurate starting position
locationTracker.setMinAccuracy(5f) // meters

// Wait for accurate position before starting
locationTracker.setLocationListener(object : LocationListener {
    override fun onLocationChanged(location: Location) {
        if (location.accuracy <= 5f) {
            // Position is accurate enough
            startNavigation(destination)
        } else {
            showMessage("Improving position accuracy...")
        }
    }
})
// Configure instruction distances
val instructionConfig = InstructionConfig(
    earlyWarningDistance = 50f, // Show "Turn ahead" at 50m
    turnAnnouncementDistance = 20f, // Show "Turn now" at 20m
    arrivalAnnouncementDistance = 10f, // Arrival at 10m
    verbosity = InstructionVerbosity.DETAILED
)

instructionManager.setInstructionConfig(instructionConfig)
navigationManager.setNavigationListener(object : NavigationListener {
    override fun onPositionUpdated(location: Location) {
        Log.d("Nav", "Position: ${location.x}, ${location.y}, ${location.z}")
        Log.d("Nav", "Floor: ${location.floor}")
        Log.d("Nav", "Accuracy: ${location.accuracy}m")
    }

    override fun onInstructionChanged(instruction: NavigationInstruction) {
        Log.d("Nav", "Instruction: ${instruction.text}")
        Log.d("Nav", "Distance: ${instruction.distance}m")
        Log.d("Nav", "Type: ${instruction.type}")
    }

    override fun onRouteDeviation(distance: Float) {
        Log.w("Nav", "Off route by ${distance}m")
    }
})

Location Tracking Issues

Inaccurate Position

Symptom

User position jumps around or shows incorrect location.

Solutions:

locationTracker.apply {
    // Use multiple positioning sources
    addProvider(LocationProvider.WIFI, priority = 10)
    addProvider(LocationProvider.BLUETOOTH, priority = 8)
    addProvider(LocationProvider.SENSOR_FUSION, priority = 6)
    addProvider(LocationProvider.PDR, priority = 4)

    // Enable sensor fusion for smoothing
    setSensorFusionConfig(SensorFusionConfig(
        enableAccelerometer = true,
        enableGyroscope = true,
        enableMagnetometer = true,
        enableStepDetector = true
    ))
}
// Apply filtering for smooth tracking
class SmoothedLocationTracker(context: Context) : LocationTracker(context) {

    private val kalmanFilter = KalmanFilter()

    override fun processLocationUpdate(rawLocation: Location) {
        // Filter noisy location data
        val smoothedLocation = kalmanFilter.filter(rawLocation)

        // Only update if change is significant
        if (isSignificantChange(smoothedLocation)) {
            notifyLocationUpdate(smoothedLocation)
        }
    }

    private fun isSignificantChange(location: Location): Boolean {
        val lastLocation = getLastLocation() ?: return true
        val distance = location.distanceTo(lastLocation)
        return distance > 0.5f // 50cm threshold
    }
}
// Avoid overwhelming the system
locationTracker.apply {
    setUpdateInterval(1000) // Update every 1 second
    setFastestInterval(500) // But not faster than 500ms
    setMinAccuracy(5f) // Only accept positions within 5m accuracy
}

Location Not Updating

Symptom

Position marker stays frozen or doesn't move.

Solutions:

// Verify all required permissions
val requiredPermissions = arrayOf(
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION,
    Manifest.permission.BLUETOOTH,
    Manifest.permission.BLUETOOTH_ADMIN,
    Manifest.permission.ACCESS_WIFI_STATE
)

val missingPermissions = requiredPermissions.filter {
    ContextCompat.checkSelfPermission(this, it) != 
        PackageManager.PERMISSION_GRANTED
}

if (missingPermissions.isNotEmpty()) {
    ActivityCompat.requestPermissions(
        this,
        missingPermissions.toTypedArray(),
        PERMISSIONS_REQUEST_CODE
    )
}
// Reset location tracking
fun resetLocationTracking() {
    locationTracker.stopTracking()

    // Wait a moment
    Handler(Looper.getMainLooper()).postDelayed({
        locationTracker.startTracking()
    }, 1000)
}
// Monitor provider availability
locationTracker.setProviderListener(object : ProviderListener {
    override fun onProviderEnabled(provider: LocationProvider) {
        Log.d("Location", "Provider enabled: ${provider.name}")
    }

    override fun onProviderDisabled(provider: LocationProvider) {
        Log.w("Location", "Provider disabled: ${provider.name}")
        // Try alternative providers
    }

    override fun onProviderError(provider: LocationProvider, error: String) {
        Log.e("Location", "Provider error: ${provider.name} - $error")
    }
})

UI Component Issues

UI Components Not Visible

Symptom

UI components like search bar or navigation panel don't appear.

Solutions:

// Ensure components are added to scene view
val searchBar = SearchBar(this)
val navigationPanel = LiveNavigationPanel(this)

sceneView.apply {
    addUIComponent(searchBar)
    addUIComponent(navigationPanel)
}

// Verify components were added
Log.d("UI", "Component count: ${sceneView.getUIComponentCount()}")
// Ensure components are on top
searchBar.apply {
    bringToFront()
    elevation = 8.dp
}
override fun onResume() {
    super.onResume()
    sceneView.onResume()
    // Restore UI component visibility
    searchBar.visibility = View.VISIBLE
}

Search Bar Not Responding

Symptom

Clicking search bar doesn't show keyboard or suggestions.

Solutions:

searchBar.apply {
    // Ensure touch events are enabled
    isClickable = true
    isFocusable = true
    isFocusableInTouchMode = true

    // Request focus on click
    setOnClickListener {
        requestFocus()
        showKeyboard()
    }
}
// Set up search data source
searchBar.setSearchProvider { query ->
    if (query.length < 2) {
        return@setSearchProvider emptyList()
    }

    // Return search results
    poiManager.search(query).map { poi ->
        SearchResult(
            id = poi.id,
            title = poi.name,
            subtitle = poi.category,
            location = poi.location
        )
    }
}

Performance Problems

Low Frame Rate

Symptom

App runs slowly with stuttering or lag.

Solutions:

// Optimize for performance
sceneView.displayConfig = DisplayConfig(
    renderQuality = DisplayConfig.RenderQuality.LOW,
    shadowsEnabled = false,
    ambientOcclusion = false,
    antiAliasing = false
)

// Limit frame rate
sceneView.maxFrameRate = 30
// Switch to 2D for better performance
sceneView.setRenderMode(RenderMode.MODE_2D)
// Simplify route visualization
sceneView.routeRenderConfig = RouteRenderConfig(
    segmentCount = 20, // Reduce from default
    smoothing = false,
    animationsEnabled = false
)

High Memory Usage

Symptom

App uses excessive memory or crashes with OutOfMemoryError.

Solutions:

override fun onLowMemory() {
    super.onLowMemory()
    sceneView.clearCache()
    sceneView.reduceTextureQuality()
}

override fun onTrimMemory(level: Int) {
    super.onTrimMemory(level)
    when (level) {
        ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW -> {
            sceneView.clearCache()
        }
    }
}
override fun onDestroy() {
    // Clean up resources
    navigationManager.destroy()
    locationTracker.stopTracking()
    sceneView.onDestroy()
    super.onDestroy()
}

Permission Issues

Permission Denied Permanently

Symptom

User denied permission and selected "Don't ask again".

Solutions:

fun showPermissionSettingsDialog() {
    AlertDialog.Builder(this)
        .setTitle("Location Permission Required")
        .setMessage(
            "Navigation requires location permission. " +
            "Please enable it in app settings."
        )
        .setPositiveButton("Open Settings") { _, _ ->
            val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
            intent.data = Uri.fromParts("package", packageName, null)
            startActivity(intent)
        }
        .setNegativeButton("Cancel", null)
        .show()
}

Build & Integration Issues

Gradle Sync Failed

Error Message

Failed to resolve: com.machinestalk:indoornavigationengine:0.4.0-alpha

Solutions:

// build.gradle (project level)
allprojects {
    repositories {
        google()
        mavenCentral()
        // Add your repository here
    }
}
// Use correct version number
dependencies {
    implementation("com.machinestalk:indoornavigationengine:0.4.0-alpha")
}

Java 17 Compilation Error

Error Message

Unsupported class file major version 61

Solutions:

// build.gradle (module level)
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }

    kotlinOptions {
        jvmTarget = "17"
    }
}

Runtime Crashes

NullPointerException

Common Locations

  • Map data not loaded before use
  • Components not initialized
  • Missing null checks

Solutions:

// Always check for null
val mapData = JsonUtil.LoadJsonFromAsset(context, "maps/venue.json")
if (mapData == null) {
    Log.e("Error", "Failed to load map")
    return
}

sceneView.setMapData(mapData)

OutOfMemoryError

Cause

Memory leak or excessive resource usage.

Solutions:

// Implement proper cleanup
override fun onDestroy() {
    navigationManager.destroy()
    locationTracker.stopTracking()
    sceneView.onDestroy()
    super.onDestroy()
}

Still Need Help?

If you're still experiencing issues after trying these solutions:

  • Contact Support


    Get help from our technical support team

    Contact Us

  • Check FAQ


    Browse frequently asked questions

    View FAQ

  • Documentation


    Explore comprehensive documentation

    Browse Docs

  • Report Bug


    Submit a detailed bug report

    Report Issue


Debug Tips

Enable Verbose Logging

// Enable detailed logging
if (BuildConfig.DEBUG) {
    MineLogger.setLogLevel(MineLogger.Level.VERBOSE)
    sceneView.showDebugOverlay = true
    sceneView.showFpsCounter = true
}

Use LogCat Filters

# Filter by tag
adb logcat MINE:D *:S

# Filter by package
adb logcat | grep com.example.myapp

Capture Debug Info

fun captureDebugInfo(): String {
    return buildString {
        appendLine("=== MINE Debug Info ===")
        appendLine("Version: ${BuildConfig.VERSION_NAME}")
        appendLine("Device: ${Build.MODEL}")
        appendLine("Android: ${Build.VERSION.RELEASE}")
        appendLine("Memory: ${getAvailableMemory()}MB")
        appendLine("Location providers: ${locationTracker.getActiveProviders()}")
        appendLine("Map loaded: ${sceneView.isMapLoaded()}")
        appendLine("Navigation active: ${navigationManager.isNavigating()}")
    }
}

Problem Solved?

If these solutions helped, consider sharing your experience or contributing additional troubleshooting tips!