A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://developers.arcgis.com/kotlin/device-location/tutorials/display-device-location/ below:

Display device location | ArcGIS Maps SDK for Kotlin

Learn how to display the current device location on a map or scene.

You can display the device location on a map or scene. This is important for workflows that require the user's current location, such as finding nearby businesses, navigating from the current location, or identifying and collecting geospatial information.

By default, location display uses the device's location provider. Your app can also process input from other location providers, such as an external GPS receiver or a provider that returns a simulated location. For more information, see the Show device location topic.

Prerequisites

Before starting this tutorial, you need the following:

  1. An ArcGIS Location Platform or ArcGIS Online account.

  2. A development and deployment environment that meets the system requirements.

  3. An IDE for Android development in Kotlin.

Note

It is recommended that you use the latest stable version Android Studio to create this tutorial app. The code described in the steps below, however, should work in any up-to-date Android IDE that supports Kotlin.

Develop or download

You have two options for completing this tutorial:

  1. Option 1: Develop the code or
  2. Option 2: Download the completed solution
Option 1: Develop the code Open an Android Studio project
  1. Open the project you created by completing the Display a map tutorial.

  2. Continue with the following instructions to display the current device location on a map or scene.

  3. Modify the old project for use in this new tutorial.

    1. On your file system, delete the .idea folder, if present, at the top level of your project.

    2. In the Android view, open app > res > values > strings.xml.

      In the <string name="app_name"> element, change the text content to Display device location.

      strings.xml

      Use dark colors for code blocks

      1
      2
      3
      4
      5
      <resources>
      
          <string name="app_name">Display device location</string>
      
      </resources>
    3. In the Android view, open Gradle Scripts > settings.gradle.kts.

      Change the value of rootProject.name to "Display device location".

      settings.gradle.kts

      Expand

      Use dark colors for code blocks
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      dependencyResolutionManagement {
          repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
          repositories {
              google()
              mavenCentral()
              maven { url = uri("https://esri.jfrog.io/artifactory/arcgis") }
          }
      }
      
      rootProject.name = "Display device location"
      include(":app")
    4. Click File > Sync Project with Gradle files. Android Studio will recognize your changes and create a new .idea folder.

Add import statements
  1. In the Android view, open app > kotlin+java > com.example.app > MainScreen.kt. Replace the import statements with the imports needed for this tutorial.

    MainScreen.kt

    Use dark colors for code blocks

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    @file:OptIn(ExperimentalMaterial3Api::class)
    
    package com.example.app.screens
    
    import android.Manifest
    import android.content.Context
    import android.content.pm.PackageManager
    import android.widget.Toast
    import androidx.activity.compose.rememberLauncherForActivityResult
    import androidx.activity.result.contract.ActivityResultContracts
    import androidx.compose.foundation.layout.fillMaxSize
    import androidx.compose.foundation.layout.padding
    import androidx.compose.material3.ExperimentalMaterial3Api
    import androidx.compose.material3.Scaffold
    import androidx.compose.material3.Text
    import androidx.compose.material3.TopAppBar
    import androidx.compose.runtime.Composable
    import androidx.compose.runtime.LaunchedEffect
    import androidx.compose.runtime.remember
    import androidx.compose.runtime.rememberCoroutineScope
    import androidx.compose.ui.Modifier
    import androidx.compose.ui.platform.LocalContext
    import androidx.compose.ui.res.stringResource
    import androidx.core.content.ContextCompat
    import com.arcgismaps.ArcGISEnvironment
    import com.arcgismaps.location.LocationDisplayAutoPanMode
    import com.arcgismaps.mapping.ArcGISMap
    import com.arcgismaps.mapping.BasemapStyle
    import com.arcgismaps.mapping.Viewpoint
    import com.arcgismaps.toolkit.geoviewcompose.MapView
    import com.arcgismaps.toolkit.geoviewcompose.rememberLocationDisplay
    import com.example.app.R
    import kotlinx.coroutines.launch
    
    
Check location permissions
  1. In the Android view, open app > manifests > AndroidManifest.xml.

    In AndroidManifest.xml, add permissions for coarse and fine location.

    AndroidManifest.xml

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    
        <uses-permission android:name="android.permission.INTERNET" />
    
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
  2. In MainScreen.kt, create a top-level function named checkPermissions() to check whether both coarse and fine location permissions are granted. This function takes the current local Context as a parameter, and returns true if both permissions are granted and false otherwise.

    MainScreen.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    fun checkPermissions(context: Context): Boolean {
        // Check permissions to see if both permissions are granted.
        // Coarse location permission.
        val permissionCheckCoarseLocation = ContextCompat.checkSelfPermission(
            context,
            Manifest.permission.ACCESS_COARSE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
        // Fine location permission.
        val permissionCheckFineLocation = ContextCompat.checkSelfPermission(
            context,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
    
        return permissionCheckCoarseLocation && permissionCheckFineLocation
    }
    
Show device location if permissions were granted
  1. In the MainScreen composable, you will add code that creates a location display and sets the auto pan mode.

    Get the local Context and use it to set the ArcGISEnvironment.applicationContext property.

    MainScreen.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    @Composable
    fun MainScreen() {
    
        val context = LocalContext.current
        val coroutineScope = rememberCoroutineScope()
    
        ArcGISEnvironment.applicationContext = context.applicationContext
    
        val map = remember { createMap() }
    
        Scaffold(
            topBar = { TopAppBar(title = { Text(text = stringResource(id = R.string.app_name)) }) }
        ) {
            MapView(
                modifier = Modifier.fillMaxSize().padding(it),
                arcGISMap = map,
    
            )
        }
    
    }
    
  2. Create a LocationDisplay by calling the composable function rememberLocationDisplay() defined in the ArcGIS Maps SDK for Kotlin Toolkit. Then set a LocationDisplayAutoPanMode that centers the map at the device location.

    MainScreen.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    @Composable
    fun MainScreen() {
    
        val context = LocalContext.current
        val coroutineScope = rememberCoroutineScope()
    
        ArcGISEnvironment.applicationContext = context.applicationContext
    
        // Create and remember a location display with a recenter auto pan mode.
        val locationDisplay = rememberLocationDisplay().apply {
            setAutoPanMode(LocationDisplayAutoPanMode.Recenter)
        }
    
        val map = remember { createMap() }
    
        Scaffold(
            topBar = { TopAppBar(title = { Text(text = stringResource(id = R.string.app_name)) }) }
        ) {
            MapView(
                modifier = Modifier.fillMaxSize().padding(it),
                arcGISMap = map,
    
            )
        }
    
    }
    
  3. Set the locationDisplay property of MapView using locationDisplay, which we just created.

    MainScreen.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    @Composable
    fun MainScreen() {
    
        val context = LocalContext.current
        val coroutineScope = rememberCoroutineScope()
    
        ArcGISEnvironment.applicationContext = context.applicationContext
    
        // Create and remember a location display with a recenter auto pan mode.
        val locationDisplay = rememberLocationDisplay().apply {
            setAutoPanMode(LocationDisplayAutoPanMode.Recenter)
        }
    
        val map = remember { createMap() }
    
        Scaffold(
            topBar = { TopAppBar(title = { Text(text = stringResource(id = R.string.app_name)) }) }
        ) {
            MapView(
                modifier = Modifier.fillMaxSize().padding(it),
                arcGISMap = map,
    
                locationDisplay = locationDisplay
    
            )
        }
    
    }
    
  4. You will start location display, provided both permissions were granted.

    To do so, call checkPermissions(), which returns true if both coarse and fine location permissions are granted. If the return value is true, call the LaunchedEffect composable. In the LaunchedEffect block, call start() on the data source for the location display.

    MainScreen.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    @Composable
    fun MainScreen() {
    
        val context = LocalContext.current
        val coroutineScope = rememberCoroutineScope()
    
        ArcGISEnvironment.applicationContext = context.applicationContext
    
        // Create and remember a location display with a recenter auto pan mode.
        val locationDisplay = rememberLocationDisplay().apply {
            setAutoPanMode(LocationDisplayAutoPanMode.Recenter)
        }
    
        if (checkPermissions(context)) {
            // Permissions are already granted.
            LaunchedEffect(Unit) {
                locationDisplay.dataSource.start()
            }
        } else {
    
        }
    
        val map = remember { createMap() }
    
        Scaffold(
            topBar = { TopAppBar(title = { Text(text = stringResource(id = R.string.app_name)) }) }
        ) {
            MapView(
                modifier = Modifier.fillMaxSize().padding(it),
                arcGISMap = map,
    
                locationDisplay = locationDisplay
    
            )
        }
    
    }
    
Request location permissions if they were not granted
  1. Create a composable function named RequestPermissions that takes two parameters: one named context and the other named onPermissionsGranted, which is a function to be executed after requested permissions have been granted.

    MainScreen.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    @Composable
    fun RequestPermissions(context: Context, onPermissionsGranted: () -> Unit) {
    
    }
    
  2. In RequestPermissions, create an ActivityResultLauncher by calling the composable function rememberLauncherForActivityResult().

    Note

    The trailing lambda for rememberLauncherForActivityResult() is passed a permissions parameter that is a Map where key is a permission name and value is a Boolean indicating whether the permission is granted or not.

    Check that the value for each map entry in permissions is true. If both values are true, call the onPermissionsGranted callback function. If values are not both true, show an error message.

    You can show an error message in various ways. The code in this tutorial calls a custom function named showError(), which is defined like this:

    MainScreen.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    fun showError(context: Context, message: String) {
        Toast.makeText(context, message, Toast.LENGTH_LONG).show()
    }

    MainScreen.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    @Composable
    fun RequestPermissions(context: Context, onPermissionsGranted: () -> Unit) {
    
        // Create an activity result launcher using permissions contract and handle the result.
        val activityResultLauncher = rememberLauncherForActivityResult(
                ActivityResultContracts.RequestMultiplePermissions()
            ) { permissions ->
                // Check if both fine & coarse location permissions are true.
                if (permissions.all { it.value }) {
                    onPermissionsGranted()
                } else {
                    showError(context, "Location permissions were denied")
                }
            }
    
    }
    
  3. Call the LaunchedEffect composable. In the LaunchedEffect block, execute the activity result launcher by calling activityResultLauncher.launch() and passing the permissions you are requesting: fine and coarse location permissions.

    MainScreen.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    @Composable
    fun RequestPermissions(context: Context, onPermissionsGranted: () -> Unit) {
    
        // Create an activity result launcher using permissions contract and handle the result.
        val activityResultLauncher = rememberLauncherForActivityResult(
                ActivityResultContracts.RequestMultiplePermissions()
            ) { permissions ->
                // Check if both fine & coarse location permissions are true.
                if (permissions.all { it.value }) {
                    onPermissionsGranted()
                } else {
                    showError(context, "Location permissions were denied")
                }
            }
    
        LaunchedEffect(Unit) {
            activityResultLauncher.launch(
                // Request both fine and coarse location permissions.
                arrayOf(
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION
                )
            )
        }
    
    }
    
  4. Last, in the MainScreen composable, find the code that checks if coarse and fine location permissions were both granted.

    MainScreen.kt

    Expand

    Use dark colors for code blocks Copy
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    @Composable
    fun MainScreen() {
    
        val context = LocalContext.current
        val coroutineScope = rememberCoroutineScope()
    
        ArcGISEnvironment.applicationContext = context.applicationContext
    
        // Create and remember a location display with a recenter auto pan mode.
        val locationDisplay = rememberLocationDisplay().apply {
            setAutoPanMode(LocationDisplayAutoPanMode.Recenter)
        }
    
        if (checkPermissions(context)) {
            // Permissions are already granted.
            LaunchedEffect(Unit) {
                locationDisplay.dataSource.start()
            }
        } else {
    
        }
    
        val map = remember { createMap() }
    
        Scaffold(
            topBar = { TopAppBar(title = { Text(text = stringResource(id = R.string.app_name)) }) }
        ) {
            MapView(
                modifier = Modifier.fillMaxSize().padding(it),
                arcGISMap = map,
    
                locationDisplay = locationDisplay
    
            )
        }
    
    }
    
  5. In the else block (permissions were not granted), call RequestPermissions and pass a trailing lambda as the onPermissionGranted parameter. The lambda will be called after the permissions are granted. In the lambda, start the data source of the location display.

    MainScreen.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    @Composable
    fun MainScreen() {
    
        val context = LocalContext.current
        val coroutineScope = rememberCoroutineScope()
    
        ArcGISEnvironment.applicationContext = context.applicationContext
    
        // Create and remember a location display with a recenter auto pan mode.
        val locationDisplay = rememberLocationDisplay().apply {
            setAutoPanMode(LocationDisplayAutoPanMode.Recenter)
        }
    
        if (checkPermissions(context)) {
            // Permissions are already granted.
            LaunchedEffect(Unit) {
                locationDisplay.dataSource.start()
            }
        } else {
    
            RequestPermissions(
                context = context,
                onPermissionsGranted = {
                    coroutineScope.launch {
                        locationDisplay.dataSource.start()
                    }
                }
            )
    
        }
    
        val map = remember { createMap() }
    
        Scaffold(
            topBar = { TopAppBar(title = { Text(text = stringResource(id = R.string.app_name)) }) }
        ) {
            MapView(
                modifier = Modifier.fillMaxSize().padding(it),
                arcGISMap = map,
    
                locationDisplay = locationDisplay
    
            )
        }
    
    }
    
Run your app

Click Run > Run > app to run the app.

In Android Studio, you have two choices for running your app: an actual Android device or the Android Emulator.

Android device

Connect your computer to your Android device, using USB or Wi-Fi. For more details, see How to connect your Android device.

Android Emulator

Create an AVD (Android Virtual Device) to run in the Android Emulator. For details, see Run apps on the Android Emulator.

Selecting a device

When you build and run an app in Android Studio, you must first select a device. From the Android Studio toolbar, you can access the drop-down list of your currently available devices, both virtual and physical.

.

If you cannot access the list on the toolbar, click Tools > Device Manager.

The app should display a permissions popup, in which you must tap Precise (for fine permissions) or Approximate (for coarse permissions). After you do so, your current location should display on the map. Different location symbols are used depending on the auto pan mode and whether a location is acquired. See LocationDisplayAutoPanMode for details.

By default, a round blue symbol is used to display the device's location. The location data source tries to get the most accurate location available but depending upon signal strength, satellite positions, and other factors, the location reported could be an approximation. A semi-transparent circle around the location symbol indicates the range of accuracy. As the device moves and location updates are received, the location symbol will be repositioned on the map.

Alternatively, you can download the tutorial solution, as follows.

Option 2: Download the solution
  1. Click the Download solution link in the right-hand side of this page.

  2. Unzip the file to a location on your machine.

  3. Run Android Studio.

  4. Go to File > Open.... Navigate to the solution folder and click Open.

    On Windows: If you are in the Welcome to Android Studio dialog, click Open and navigate to the solution folder. Then click Open.

Since the downloaded solution does not contain authentication credentials, you must first set up authentication to create credentials, and then add the developer credentials to the solution.

Set up authentication

To access the secure ArcGIS location services used in this tutorial, you must implement API key authentication or user authentication using an ArcGIS Location Platform or an ArcGIS Online account.

You can implement API key authentication or user authentication in this tutorial. Compare the differences below:

API key authentication

Learn more in API key authentication.

User authentication

Learn more in User authentication.

Security and authentication guide

To learn more about the different types of authentication, visit Types of authentication.

Create a new API key access token with privileges to access the secure resources used in this tutorial.

  1. Complete the Create an API key tutorial and create an API key with the following privilege(s):

  2. Copy and paste the API key access token into a safe location. It will be used in a later step.

Create new OAuth credentials to access the secure resources used in this tutorial.

  1. Complete the Create OAuth credentials for user authentication tutorial to obtain a Client ID and Redirect URL.

    A Client ID uniquely identifies your app on the authenticating server. If the server cannot find an app with the provided Client ID, it will not proceed with authentication.

    The Redirect URL (also referred to as a callback url) is used to identify a response from the authenticating server when the system returns control back to your app after an OAuth login. Since it does not necessarily represent a valid endpoint that a user could navigate to, the redirect URL can use a custom scheme, such as my-app://auth. It is important to make sure the redirect URL used in your app's code matches a redirect URL configured on the authenticating server.

  2. Copy and paste the Client ID and Redirect URL into a safe location. They will be used in a later step.

All users that access this application need account privileges to access the ArcGIS Basemap Styles service.

Set developer credentials in the solution

To allow your app users to access ArcGIS location services, use the developer credentials that you created in the Set up authentication step to authenticate requests for resources.

  1. In the Android view of Android Studio, open app > kotlin+java > com.example.app > MainActivity. Set the AuthenticationMode to .API_KEY.

    MainActivity.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    class MainActivity : ComponentActivity() {
    
        private enum class AuthenticationMode { API_KEY, USER_AUTH }
    
        private val authenticationMode = AuthenticationMode.API_KEY
    
  2. Set the apiKey property with your API key access token.

    MainActivity.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            when (authenticationMode) {
                AuthenticationMode.API_KEY -> {
    
                    ArcGISEnvironment.apiKey = ApiKey.create("YOUR_ACCESS_TOKEN")
    
                }
    

Best Practice: The access token is stored directly in the code as a convenience for this tutorial. Do not store credentials directly in source code in a production environment.

  1. In the Android view of Android Studio, open app > kotlin+java > com.example.app > MainActivity. Set the AuthenticationMode to .USER_AUTH.

    MainActivity.kt

    Use dark colors for code blocks

    1
    2
    3
    4
    class MainActivity : ComponentActivity() {
        private enum class AuthenticationMode { API_KEY, USER_AUTH }
    
        private val authenticationMode = AuthenticationMode.USER_AUTH
  2. Set your clientID and redirectURL values. You must use the RedirectURL that you supplied for your app in the user authentication part of the Set up authentication step.

    MainActivity.kt

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
                AuthenticationMode.USER_AUTH -> {
                    authenticatorState.oAuthUserConfigurations = listOf(
                        OAuthUserConfiguration(
                            portalUrl = "https://www.arcgis.com",
    
                            clientId = "YOUR_CLIENT_ID",
                            redirectUrl = "YOUR_REDIRECT_URL"
    
                        )
                    )
    
  3. Open app > manifests > AndroidManifest.xml.

  4. Set the android:scheme and android:host using the scheme and host from your RedirectURL.

    A redirectURL is composed of a scheme and a host component. The format for the redirect url is scheme://host. For example, if the redirect url is myscheme://myhost then the scheme is myscheme and the host is myhost.

    AndroidManifest.xml

    Expand

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
                    <data
                        android:scheme="your_redirect_url_scheme"
                        android:host="your_redirect_url_host" />
    

Best Practice: The OAuth credentials are stored directly in the code as a convenience for this tutorial. Do not store credentials directly in source code in a production environment.

Run the app

Click Run > Run > app to run the app.

In Android Studio, you have two choices for running your app: an actual Android device or the Android Emulator.

Android device

Connect your computer to your Android device, using USB or Wi-Fi. For more details, see How to connect your Android device.

Android Emulator

Create an AVD (Android Virtual Device) to run in the Android Emulator. For details, see Run apps on the Android Emulator.

Selecting a device

When you build and run an app in Android Studio, you must first select a device. From the Android Studio toolbar, you can access the drop-down list of your currently available devices, both virtual and physical.

.

If you cannot access the list on the toolbar, click Tools > Device Manager.

The app should display a permissions popup, in which you must tap Precise (for fine permissions) or Approximate (for coarse permissions). After you do so, your current location should display on the map. Different location symbols are used depending on the auto pan mode and whether a location is acquired. See LocationDisplayAutoPanMode for details.

By default, a round blue symbol is used to display the device's location. The location data source tries to get the most accurate location available but depending upon signal strength, satellite positions, and other factors, the location reported could be an approximation. A semi-transparent circle around the location symbol indicates the range of accuracy. As the device moves and location updates are received, the location symbol will be repositioned on the map.

What's next?

Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials:


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4