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.
PrerequisitesBefore starting this tutorial, you need the following:
An ArcGIS Location Platform or ArcGIS Online account.
A development and deployment environment that meets the system requirements.
An IDE for Android development in Kotlin.
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 downloadYou have two options for completing this tutorial:
Option 1: Develop the code Open an Android Studio projectOpen the project you created by completing the Display a map tutorial.
Continue with the following instructions to display the current device location on a map or scene.
Modify the old project for use in this new tutorial.
On your file system, delete the .idea folder, if present, at the top level of your project.
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>
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 blocks1
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")
Click File > Sync Project with Gradle files. Android Studio will recognize your changes and create a new .idea folder.
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
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 blocks1
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" />
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 blocks1
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
}
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 blocks1
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,
)
}
}
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 blocks1
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,
)
}
}
Set the locationDisplay
property of MapView
using locationDisplay
, which we just created.
MainScreen.kt
Expand
Use dark colors for code blocks1
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
)
}
}
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 blocks1
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
)
}
}
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 blocks1
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) {
}
In RequestPermissions
, create an ActivityResultLauncher
by calling the composable function rememberLauncherForActivityResult()
.
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 blocks1
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 blocks1
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")
}
}
}
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 blocks1
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
)
)
}
}
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 Copy1
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
)
}
}
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 blocks1
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
)
}
}
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 deviceConnect your computer to your Android device, using USB or Wi-Fi. For more details, see How to connect your Android device.
Android EmulatorCreate an AVD (Android Virtual Device) to run in the Android Emulator. For details, see Run apps on the Android Emulator.
Selecting a deviceWhen 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 solutionClick the Download solution link in the right-hand side of this page.
Unzip the file to a location on your machine.
Run Android Studio.
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 authenticationTo 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 guideTo 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.
Complete the Create an API key tutorial and create an API key with the following privilege(s):
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.
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.
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 solutionTo 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.
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 blocks1
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
Set the apiKey
property with your API key access token.
MainActivity.kt
Expand
Use dark colors for code blocks1
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.
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
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 blocks1
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"
)
)
Open app > manifests > AndroidManifest.xml.
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 blocks1
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 appClick 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 deviceConnect your computer to your Android device, using USB or Wi-Fi. For more details, see How to connect your Android device.
Android EmulatorCreate an AVD (Android Virtual Device) to run in the Android Emulator. For details, see Run apps on the Android Emulator.
Selecting a deviceWhen 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